从发出 api 请求的函数调用中取回响应或错误
Getting back a response or error from a function call that makes api request
我尝试向 Sendinblue 发出 api 请求以创建新联系人。我的代码可以工作,但问题是我没有正确处理错误。
我创建了一个组件,并在另一个文件中创建了发出请求的函数。该函数在表单提交时被调用,结果被分配给一个变量,并且基于变量值的 if/else 应该向用户显示一条消息(此时只是一个要检查的日志)。
目前 'result' 变量在 if/else 中始终未定义,这是合乎逻辑的,因为请求需要一些时间。但是我不知道如何让它工作。
我试过的东西:
- 而不是 if/else 使用 then/catch.
- 使 saveContact 函数成为异步函数。
分量:
import React, { useState } from "react";
import saveContact from "../js/form";
function Form() {
const [firstname, setFirstname] = useState("");
const [lastname, setLastname] = useState("");
const [email, setEmail] = useState("");
const [error, setError] = useState(false);
const [succes, setSucces] = useState(false);
const errorMessage = error
? "Something went wrong, sorry. Try again later."
: "";
const succesMessage = succes ? "Thank you, subscribed succesfully!" : "";
const handleForm = (e) => {
e.preventDefault();
const result = saveContact(firstname, lastname, email);
console.log(result);
if (result) {
console.log("Created");
} else {
console.log("Error");
}
};
return (
<div className="row">
<div className="col-lg-8 mx-auto">
<form
id="contactForm"
name="sentMessage"
noValidate="novalidate"
onSubmit={handleForm}
>
<div className="control-group">
<div className="form-group floating-label-form-group controls mb-0 pb-2">
<label>Firstname</label>
<input
className="form-control"
id="firstname"
type="text"
placeholder="Firstname"
required="required"
value={firstname}
onChange={(e) => setFirstname(e.target.value)}
data-validation-required-message="Please enter your firstname."
/>
<p className="help-block text-danger"></p>
</div>
</div>
<div className="control-group">
<div className="form-group floating-label-form-group controls mb-0 pb-2">
<label>Lastname</label>
<input
className="form-control"
id="lastname"
type="text"
placeholder="Lastname"
required="required"
value={lastname}
onChange={(e) => setLastname(e.target.value)}
data-validation-required-message="Please enter your lastname."
/>
<p className="help-block text-danger"></p>
</div>
</div>
<div className="control-group">
<div className="form-group floating-label-form-group controls mb-0 pb-2">
<label>Email Address</label>
<input
className="form-control"
id="email"
type="email"
placeholder="Email Address"
required="required"
value={email}
onChange={(e) => setEmail(e.target.value)}
data-validation-required-message="Please enter your email address."
/>
<p className="help-block text-danger"></p>
</div>
</div>
<br />
<div id="success">{succesMessage}</div>
<div id="success">{errorMessage}</div>
<div className="form-group">
<button
className="btn btn-primary btn-xl"
id="sendMessageButton"
type="submit"
>
Send
</button>
</div>
</form>
</div>
</div>
);
}
export default Form;
发出请求的函数:
var request = require("request");
function saveContact(firstname, lastname, email) {
var options = {
method: "POST",
url: "https://api.sendinblue.com/v3/contacts",
headers: {
accept: "application/json",
"content-type": "application/json",
"api-key":
<api-key>,
},
body: {
listIds: [4],
updateEnabled: false,
email: email,
emailBlacklisted: false,
smsBlacklisted: false,
attributes: {
LASTNAME: firstname,
FIRSTNAME: lastname,
},
},
json: true,
};
try {
request(options, function (error, response, body) {
if (error) {
throw new Error(error);
} else {
return body;
}
});
} catch (error) {
return error;
}
}
export default saveContact;
经过一番搜索,我终于找到了答案。
在发出请求的函数中,我添加了一个回调并返回函数,如下所示:
const response = request(options, function (error, response, body) {
if (error) {
callback(error);
} else {
callback({ body, response });
}
});
return response;
并且在组件a中必须在主体中使用if/else创建一个异步完成函数,如下所示:
const handleForm = (e) => {
e.preventDefault();
saveContact(firstname, lastname, email, async (result) => {
if (result.response.statusCode === 201) {
const result = await user.functions.updateUserCount();
// console.log("RESULT", result);
setSucces("Thank you, subscribed succesfully!");
setErrorMessage("");
setFirstname("");
setLastname("");
setEmail("");
setUserCount(userCount + 1);
} else {
setErrorMessage("Something went wrong, sorry. Try again later.");
}
});
我尝试向 Sendinblue 发出 api 请求以创建新联系人。我的代码可以工作,但问题是我没有正确处理错误。
我创建了一个组件,并在另一个文件中创建了发出请求的函数。该函数在表单提交时被调用,结果被分配给一个变量,并且基于变量值的 if/else 应该向用户显示一条消息(此时只是一个要检查的日志)。
目前 'result' 变量在 if/else 中始终未定义,这是合乎逻辑的,因为请求需要一些时间。但是我不知道如何让它工作。
我试过的东西:
- 而不是 if/else 使用 then/catch.
- 使 saveContact 函数成为异步函数。
分量:
import React, { useState } from "react";
import saveContact from "../js/form";
function Form() {
const [firstname, setFirstname] = useState("");
const [lastname, setLastname] = useState("");
const [email, setEmail] = useState("");
const [error, setError] = useState(false);
const [succes, setSucces] = useState(false);
const errorMessage = error
? "Something went wrong, sorry. Try again later."
: "";
const succesMessage = succes ? "Thank you, subscribed succesfully!" : "";
const handleForm = (e) => {
e.preventDefault();
const result = saveContact(firstname, lastname, email);
console.log(result);
if (result) {
console.log("Created");
} else {
console.log("Error");
}
};
return (
<div className="row">
<div className="col-lg-8 mx-auto">
<form
id="contactForm"
name="sentMessage"
noValidate="novalidate"
onSubmit={handleForm}
>
<div className="control-group">
<div className="form-group floating-label-form-group controls mb-0 pb-2">
<label>Firstname</label>
<input
className="form-control"
id="firstname"
type="text"
placeholder="Firstname"
required="required"
value={firstname}
onChange={(e) => setFirstname(e.target.value)}
data-validation-required-message="Please enter your firstname."
/>
<p className="help-block text-danger"></p>
</div>
</div>
<div className="control-group">
<div className="form-group floating-label-form-group controls mb-0 pb-2">
<label>Lastname</label>
<input
className="form-control"
id="lastname"
type="text"
placeholder="Lastname"
required="required"
value={lastname}
onChange={(e) => setLastname(e.target.value)}
data-validation-required-message="Please enter your lastname."
/>
<p className="help-block text-danger"></p>
</div>
</div>
<div className="control-group">
<div className="form-group floating-label-form-group controls mb-0 pb-2">
<label>Email Address</label>
<input
className="form-control"
id="email"
type="email"
placeholder="Email Address"
required="required"
value={email}
onChange={(e) => setEmail(e.target.value)}
data-validation-required-message="Please enter your email address."
/>
<p className="help-block text-danger"></p>
</div>
</div>
<br />
<div id="success">{succesMessage}</div>
<div id="success">{errorMessage}</div>
<div className="form-group">
<button
className="btn btn-primary btn-xl"
id="sendMessageButton"
type="submit"
>
Send
</button>
</div>
</form>
</div>
</div>
);
}
export default Form;
发出请求的函数:
var request = require("request");
function saveContact(firstname, lastname, email) {
var options = {
method: "POST",
url: "https://api.sendinblue.com/v3/contacts",
headers: {
accept: "application/json",
"content-type": "application/json",
"api-key":
<api-key>,
},
body: {
listIds: [4],
updateEnabled: false,
email: email,
emailBlacklisted: false,
smsBlacklisted: false,
attributes: {
LASTNAME: firstname,
FIRSTNAME: lastname,
},
},
json: true,
};
try {
request(options, function (error, response, body) {
if (error) {
throw new Error(error);
} else {
return body;
}
});
} catch (error) {
return error;
}
}
export default saveContact;
经过一番搜索,我终于找到了答案。
在发出请求的函数中,我添加了一个回调并返回函数,如下所示:
const response = request(options, function (error, response, body) {
if (error) {
callback(error);
} else {
callback({ body, response });
}
});
return response;
并且在组件a中必须在主体中使用if/else创建一个异步完成函数,如下所示:
const handleForm = (e) => {
e.preventDefault();
saveContact(firstname, lastname, email, async (result) => {
if (result.response.statusCode === 201) {
const result = await user.functions.updateUserCount();
// console.log("RESULT", result);
setSucces("Thank you, subscribed succesfully!");
setErrorMessage("");
setFirstname("");
setLastname("");
setEmail("");
setUserCount(userCount + 1);
} else {
setErrorMessage("Something went wrong, sorry. Try again later.");
}
});