This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed last year.
I have this function getData which will read in a list of IDs from a JSON file. the list of IDs is stored to the idsList variable which i need to use inside another function. How do i return the value from this function
function getData(){
fetch("JSONitemIDsList.json")
.then(response => response.json())
.then(data => {
let idsList = data.ids
//return idsList
})
}
function myFunc(idsList) {
//do something with idsList
}
You can approach this in many ways. For example:
// with async / await
async function getData() {
try {
const rawData = await fetch("JSONitemIDsList.json")
const data = await rawData.json()
return data
} catch (err) {
// handle error here
console.log(err)
}
}
async function myFunc() {
const idsList = await getData()
//do something with idsList
}
or
// define first
function myFunc(idsList) {
//do something with idsList
}
function getData(){
fetch("JSONitemIDsList.json")
.then(response => response.json())
.then(data => {
// function call
myFunc(data.ids)
})
}
You can try this:
const reqResponse = fetch("JSONitemIDsList.json")
.then(response => response.json())
// I am not sure, if your data is already in the format that you need, otherwise, you can run one more .then() to format it
}
const getIdList= async () => {
const idList = await reqResponse;
console.log(idList)
// use idList to access the information you need
}
Related
I have an array and I am trying to perform an api call on each item.
Like so -
shoppingData.items.map(item => {
getItemInformation(item.id)
.then(response => response.json())
.then(data => {
JSON.parse(data.text);
});
getItemInformation is my api call -
export async function getItemInformation(id) {
try {
const req = await fetch(`**api url**`);
return await req;
} catch (e) {
console.error(e);
return 'Error';
}
}
However, once I have parsed the data, I would like to append it to a new array. This new array will then be used to render a component later down the page like so -
{newArray?.map((item, index) => (
<ShoppingItem key={index} itemDescription={item.description} itemCatergory={item.catergory} />
))}
Im having issues doing this as I have been trying to do it in a useEffect as ideally I need it to happen when the page renders. Furthermore, I tried having newArray as a state e.g const [newArray, setNewArray] = useState([]) but because I am appending items to an array, setNewArray wouldn't allow me to do this.
use Promise.all
const allItems = await Promise.all(
shoppingData.items.map(
item => getItemInformation(item.id)
.then(response => response.json())
)
);
You could also simplify this a bit by putting all the "asyncy" stuff into your getItemInformation method
const allItems = await Promise.all(
shoppingData.items.map(
item => getItemInformation(item.id)
)
);
and
export async function getItemInformation(id) {
try {
const req = await fetch(`**api url**`);
const json = await req.json();
return json;
} catch (e) {
console.error(e);
return 'Error';
}
}
Live example usiong JSONPlaceholder demo api:
async function getItemInformation(id) {
console.log("getItemInformation",id);
try {
const req = await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`);
const json = await req.json();
return json;
} catch (e) {
console.error(e);
return 'Error';
}
}
(async function testIt() {
const shoppingData = {
items: [{
id: 1
}, {
id: 2
}, {
id: 3
}]
};
const allItems = await Promise.all(
shoppingData.items.map(
item => getItemInformation(item.id)
)
);
console.log(allItems);
})()
You can easily call setNewArray(allItems) in react useEffect using this code (basically where I did consolew.log(allItems) above.
I am not sure how do you append the data to your array while you are calling async function in .map without waiting for the result.
I assume you may be trying something like this:
const parsedData = shoppingData.items.map(item => {
getItemInformation(item.id)
.then(response => response.json())
.then(data => {
JSON.parse(data.text);
});
setNewArray(parsedData);
There are two points to note. Firstly getItemInformation() is called on each item async so the order of parsedItem may not be what your expected. Secondly setNewArray() is called while parsedData's async calls may not finish.
One possible way you can try, if you really want to use .map, is using Promise.all(). Promise.all() resolves when all its promises are resolved:
const getParsedData = async() => {
return Promise.all(shoppingData.items.map(item => getItemInfo.......));
}
const data = await getParsedData();
then append data to your array.
Another simpler solution is using for-loop and await:
for (let i=0;i<shoppingData.items.length;i++){
const parsedItem = await getItemInformation(shoppingData.items[i]).........
newArray.push(parsedItem);
}
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 1 year ago.
I am trying to get data from this API using fetch, and I know a promise pending is returned, but it isn't resolving itself so I can't use the data. I don't know what I am doing wrong.
function api () {
return fetch('https://api.punkapi.com/v2/beers').then(respo => { respo.json() } ).then(data => {
const beersData = data;
return beersData;
}).catch(error => {
console.error(error)
}) ;
}
api();
console.log(beersData)
First of all, you need to remove curly bracket in first then.
respo => respo.json() is equivalent to respo => { return respo.json() }.
And second, you need to handle promise when you call api function since api() also returns Promise.
function api () {
return fetch('https://api.punkapi.com/v2/beers')
.then(respo => respo.json())
.then(data => {
const beersData = data;
return beersData;
}).catch(error => {
console.error(error)
}) ;
}
api()
.then(res => {
console.log(res);
})
This question already has answers here:
What is the scope of variables in JavaScript?
(27 answers)
Closed 2 years ago.
I thought it would be easy to find an answer to this, but it wasn't. I'm trying to make an api call from a function and then display the response in a different function. What I've got or what I want to achieve:
async getData() {
const response = await http.get("/api/");
}
async showData() {
const result = await this.getData();
console.log(result);
}
Any help is appreciated!
The getData method shouldn't need to be declared async. Just make showData an async method and await the getData response.
const getData = () => fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => response.json());
const showData = async () => {
const result = await getData();
console.log(result);
}
showData();
Here is the altered code:
getData() {
return http.get("/api/");
}
async showData() {
const result = await this.getData();
console.log(result);
}
I am trying to call a function in my action, but get the error this.setToken is not a function:
async function setToken() {
const {
credentials: { year, group, student }
} = this.props;
const fcmToken = await firebase.messaging().getToken();
if (fcmToken) {
firebase
.firestore()
.collection("users")
.doc(fcmToken)
.set({
year
})
.then(function() {
return true;
})
.catch(function(error) {
return false;
});
}
}
export function fetchEvents(id) {
const currentDateString =
moment().format("YYYY-MM-DD") + "T" + "07:00:00.000Z";
const url = xxx;
return async dispatch => {
dispatch(isLoading(true));
const setToken = await setToken(); // call here
fetch(url)
.then(response => {
return response;
})
.then(response => response.json())
.then(data => {
const { error } = data;
if (error) {
dispatch(hasErrored(error.message));
} else {
dispatch(fetchSuccessEvents(data.items));
}
navigate("Month");
dispatch(isLoading(false));
});
};
}
Any ideas?
setToken is defined as a standalone function, not a property of an instance, or of the current this, or anything like that:
async function setToken() {
So, call it like you would call any other function, without putting this in front of it.
You also cannot use the same variable name in the inner scope, else you'll refer to the inner variable (which will start out as undefined / uninitialized); assign the result to a different variable name instead:
const token = await setToken();
But your current code doesn't have setToken resolve to anything, in which case, you may simply await it, without assigning the result to anything:
await setToken();
Use
setToken()
instead of
this.setToken()
You are not in a class environment, as far as I can tell, so setToken() is not an instance or a property, but a standalone function.
If you prefer to use a class notation, you could use window.setToken().
This is a silly question but can you explain what is wrong with this code?
Why can't I perform this?
const fetch = require('node-fetch');
const fetchProm = (() => {
return fetch('https://api.github.com/users/github');
}).then((response) => {
return response.json();
}).then((json) => {
console.log(json)
});
Declaring a function is not the same as calling one
You are not calling the function that returns the promise, just declaring it. You'll need to add an additional set of parentheses before the first .then() in order to actually call the function:
const fetch = require('node-fetch');
const fetchProm = (() => {
return fetch('https://api.github.com/users/github');
})().then((response) => {
return response.json();
}).then((json) => {
console.log(json)
});
If you want to call everything at a later time, you need to place the whole thing in its own function where the promises get handled in an isolated scope:
const fetch = require('node-fetch');
const fetchProm = () => {
fetch('https://api.github.com/users/github')
.then(response => response.json())
.then(json => console.log(json));
};
fetchProm();