Reputation: 119
The following code works well and logs to the console a fetch from a website (that outputs a simple file already in json format):
getData = url => {
fetch(url)
.then(response => {
if (response.status !== 200) {
console.log(
"Looks like there was a problem. Status Code: " + response.status
);
return; //returns undefined!
}
// Examine the text in the response
response.json().then(data => {
console.log(data);
});
})
.catch(function(err) {
console.log("Fetch Error :-S", err);
});
};
getData(urlToFetch); // logs to console the website call: a json file
I want to store that fetch's content values in a variable for later use.
So, when I change:
console.log(data);
to:
return data;
I get an undefined. Any help?
Upvotes: 1
Views: 10272
Reputation: 1595
You could use ES6 async-await to get this done easily:
Using async-await, your code will look like this:
function getData(url){
return new Promise((resolve, reject) => {
fetch(url)
.then(response => {
if (response.status !== 200) {
console.log(
"Looks like there was a problem. Status Code: " + response.status
);
return; //returns undefined!
}
// Examine the text in the response
response.json().then(data => {
resolve(data);
});
})
.catch(function(err) {
console.log("Fetch Error :-S", err);
reject(err)
});
})
}
// Then call the function like so:
async function useData(){
const data = await getData(urlToFetch);
// console.log(data) ===> result;
}
Upvotes: 2
Reputation: 39250
Because you .catch
in your getData function if something else goes wrong your function will resolve undefined
as well. If you want to log it then you need to return the error as a rejecting promise so the caller can handle the error and not get an undefined value for data when the promise resolves.
You can return Promise.reject("no 200 status code")
for rejecting and return response.json()
for resolve If you want to add .then(x=>console.log(x))
you still need to return something or the thing calling getData will resolve to undefined:
getData = url => {
fetch(url)
.then(response => {
if (response.status !== 200) {
console.log(
"Looks like there was a problem. Status Code: " + response.status
);
return Promise.reject(//reject by returning a rejecting promise
"Looks like there was a problem. Status Code: " + response.status
);
}
// Examine the text in the response
response.json().then(data => {
console.log(data);
return data;//still need to return the data here
});
})
.catch(function (err) {
console.log("Fetch Error :-S", err);
//return the reject again so the caller knows something went wrong
return Promise.reject(err);
});
};
getData(urlToFetch) // logs to console the website call: a json file
.then(
x=>console.log("caller got data:",x)
)
.catch(
e=>console.log("caller got error:",e)
);
Upvotes: 2
Reputation: 7411
What happens here is, you are under then
block. Your getData functions returns the data as soon as it call fetch. It doesn't wait for the async fetch opertion to receive callback and then call function inside then.
So the return inside then function have nothing to return to. That's why it doesn't work.
Instead you can return a promise from the getData function and call then
on it to get the data. I faced a similar issue sometime ago.
An example: (not tested)
getData = url => {
new Promise(function (resolve, reject) {
fetch(url)
.then(response => {
if (response.status !== 200) {
console.log(
"Looks like there was a problem. Status Code: " + response.status
);
reject(); //returns undefined!
}
// Examine the text in the response
response.json().then(data => {
resolve(data);
});
})
.catch(function(err) {
console.log("Fetch Error :-S", err);
});
};
};
getData(urlToFetch).then(data => /*do something*/ ); // logs to console the website call: a json file
So when the data is available, you can call resolve(data) and it will invoke then method on your promise.
Hope it helps.
Upvotes: 0
Reputation: 2851
return; //returns undefined!
You aren't returning anything, so return
by itself returns undefined unless you supply it with a value.
You need to store the promise and when you need a value, you will have to resolve it. I would change this:
// Examine the text in the response
response.json().then(data => {
console.log(data);
});
to this:
// Examine the text in the response
return response.json();
Then call getData and either resolve the promise:
getData(urlToFetch).then(data => {
// Code to use data
})
Or store the promise in the variable and use it later:
let result = getData(urlToFetch);
result.then(data => {
// so whatever with data
});
Upvotes: 1