I am quite new to coding in React/JS (or any async language for that matter) and am having trouble getting an API fetch function to return the result rather than the promise.
The fetch function is:
export const i_sGETOrg = async () => {
const Cookie = new Cookies();
await fetch(process.env.REACT_APP_APIADDRESS + "/api/v1/organizations/", {
method: "GET",
headers: {
Authorization: "Bearer " + Cookie.get("JWT"),
},
}).then((response) => {
response.json().then((result) => {
console.log(result);
return result;
});
})
.catch((error) => {
APIErrorHandler(error);
});
};
This is being called from an click handling function in a separate component:
const DevOrganisations = () => {
const [newOrganization, setNewOrganization] = useState("");
const [orgs, setOrgs] = useState([]);
//get the organisations for user when component mounts
useEffect(() => {
setOrgs(i_sGETOrg());
}, []);
//handle submit a new organization to API
const handleSubmit = (event) => {
event.preventDefault();
i_sPOSTCreateOrg(newOrganization);
};
//handle get list of organizations from API
const handleGetOrg = async () => {
setOrgs(i_sGETOrg());
console.log(orgs);
};
//handle log list of organizations to the console
const handleLogOrgs = () => {
console.log(orgs);
};
return (
<div className="container">
<h3>This is the development ORGANISATIONS page</h3>
<button onClick={handleGetOrg}>Get Organisations</button>
<button onClick={handleLogOrgs}>Console.log Orgs</button>
<form onSubmit={handleSubmit}>
<label>
Organization Name:
<input
type="text"
name="CreateOrgName"
value={newOrganization}
defaultValue=""
onChange={(e) => setNewOrganization(e.target.value)}
/>
</label>
<input type="submit" value="Submit" />
</form>
<p>Your org is:</p>
{newOrganization && <p>{newOrganization}</p>}
<OrgsListDisplay orgs={orgs} />
</div>
);
};
export default DevOrganisations;
How can I make handleGetOrg function wait for i_sGetOrg to return the result so setOrgs doesn't receive the promise? Or should I be tackling the state change completely differently?
When I click the Get Organisations button the following is printed to the console:
Promise { <state>: "fulfilled", <value>: undefined }
DevOrganisations.js:27
Array(21) [ {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, … ]
Additionally, I added a button to get the orgs value, but this logs:
Promise { <state>: "fulfilled", <value>: undefined }
Any help with this would be greatly appreciated.
Thanks:)
Greg
Looks like is the issue is that you don't return the result of the fetch
request. fetch
returns a Promise
by design. You can either await
its resolved/rejected value or use a Promise
chain of then-ables. You should avoid mixing the two though.
export const i_sGETOrg = async () => {
const Cookie = new Cookies();
try {
const response = await fetch(process.env.REACT_APP_APIADDRESS + "/api/v1/organizations/", {
method: "GET",
headers: {
Authorization: "Bearer " + Cookie.get("JWT"),
},
});
const result = await response.json();
return result;
} catch(error) {
APIErrorHandler(error);
};
};
Alternatively you can directly return the Promise chain returned from the fetch
request. In this case i_sGETOrg
doesn't need to be declared async
and it still returns a promise that is settled later. Don't forget to return the next Promise from extracting the JSON data from the response.
export const i_sGETOrg = () => {
const Cookie = new Cookies();
return fetch(process.env.REACT_APP_APIADDRESS + "/api/v1/organizations/", {
method: "GET",
headers: {
Authorization: "Bearer " + Cookie.get("JWT"),
},
})
.then((response) => response.json())
.then((result) => {
console.log(result);
return result;
})
.catch((error) => {
APIErrorHandler(error);
});
};
You want to actually wait for this resolved response though.
//handle get list of organizations from API
const handleGetOrg = async () => {
setOrgs(await i_sGETOrg());
};
or
//handle get list of organizations from API
const handleGetOrg = () => {
i_sGETOrg().then(res => setOrgs(res));
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.