Not sure why when I log out the price after executing the fetchPrice() method, I am returned a promise object instead of price. Please help :)
async function fetchPrice() {
await axios
.get(assetData(selectedAsset))
.then((response) => {
return response.data.market_data.current_price.eur;
})
.catch((error) => console.log(error.response.data.error));
}
useEffect(() => {
let price = fetchPrice();
console.log("Asset Price: " price);
let assetTotal = Number(cost) / Number(price);
setAssetAmount(assetTotal);
}, [selectedAsset]);
CodePudding user response:
The problem is how you are handling the await
of your function. Normally when working with promises you use either await or a callback, not both. Because await already wait for the promise to resolve or throw an error, you directly use the return inside the function and not in the callback.
async function fetchPrice() {
try {
const price = await axios.get(assetData(selectedAsset));
return price;
} catch (e) {
console.log(error.response.data.error)
}
}
Using return
inside the callback doesn't return the object you expect since it is the result of your callback function and not the original function.
Since fetchPrice is an async function it is normal that if you try to print it you will obtain a promise. This won't change even if you correct your function as I told you above. The only way to obtain the object is by awaiting your fetch price inside the useEffect (and by making the useEffect itself async) like this:
useEffect(async () => {
let price = await fetchPrice();
console.log("Asset Price: " price);
let assetTotal = Number(cost) / Number(price);
setAssetAmount(assetTotal);
}, [selectedAsset]);
However, if you do it, you will obtain the following warning because your use effect use should be synchronous:
Effect callbacks are synchronous to prevent race conditions. Put the async function inside
The final solution? Set state directly inside the callback.
async function fetchPrice(cost) {
try {
const price = await axios.get(assetData(selectedAsset));
setAssetAmount(Number(cost)/Number(price))
} catch (e) {
console.log(error.response.data.error)
}
}
However, be careful of memory leaks when setting a state asynchronously inside a component that can be unmounted.
CodePudding user response:
You need to use either .then()
or async/await
.
Example of then()
useEffect(() => {
axios.get("https://api.github.com/users/mapbox").then((response) => {
console.log(response.data);
});
}, []);
In above code, we are using
.then()
so then will be fired when api call is done.
Example of async/await
async function axiosTest() {
const response = await axios.get("https://api.github.com/users/mapbox");
console.log(response.data, "with await");
}
In above code, we are using
await
to wait until the api call is done.
Here is the Codesandbox to check the difference with live api call