I want to write an application that requests some informations from an API. As long as this informations isn't available I don't want to continue with the rest of the application. I already tried this:
function suggestion(callback) {
xhr.open('GET', 'http://localhost:3001/');
xhr.onload = function() {
var a = JSON.parse(xhr.responseText);
console.log(a);
callback(a);
};
xhr.send();
}
var sugg = suggestion(function(lista) {
var s = [];
lista.forEach(element => {
s.push(element.event);
});
console.log(s);
return s;
});
Why sugg is returning undefined?
I want to write an application that requests some informations from an API. As long as this informations isn't available I don't want to continue with the rest of the application. I already tried this:
function suggestion(callback) {
xhr.open('GET', 'http://localhost:3001/');
xhr.onload = function() {
var a = JSON.parse(xhr.responseText);
console.log(a);
callback(a);
};
xhr.send();
}
var sugg = suggestion(function(lista) {
var s = [];
lista.forEach(element => {
s.push(element.event);
});
console.log(s);
return s;
});
Why sugg is returning undefined?
Share Improve this question edited Nov 7, 2018 at 10:54 Andreas 2,52110 gold badges24 silver badges25 bronze badges asked Nov 7, 2018 at 9:13 AtelesAteles 111 gold badge1 silver badge3 bronze badges 1-
You are not returning anything from your
suggestion
function. Since it's asynchronous, you should pass all return values you are interested in as arguments to thecallback
function instead. – Tholle Commented Nov 7, 2018 at 9:15
1 Answer
Reset to default 2As long as this informations isn't available I don't want to continue with the rest of the application
That's not how you do this with web technologies (which are what you're using if you're using React, even if it's React native). Instead, you have the application show an appropriate "loading" or "pending" state while the asynchronous operation is outstanding, and then update that state when the operation pletes.
Why sugg is returning undefined?
sugg
is undefined
because suggestion
doesn't have a return value. The result of calling a function that never does return something
is always undefined
. The fact your callback has a return
doesn't matter, nothing is using what callback()
returns in suggestion
(and even if it did, it would be doing that later, not when sugg
is being assigned to).
So taking those two bits of information together, we get:
function suggestion(callback){
// (You probably need something declaring `xhr` and assigning
// `new XMLHttpRequest()` to it here)
xhr.open('GET', 'http://localhost:3001/');
xhr.onload = function() {
var a = JSON.parse(xhr.responseText);
console.log(a);
callback(a);
};
xhr.send();
}
showPendingState(); // ***
suggestion(function(lista){
var s = [];
lista.forEach(element => {
s.push(element.event);
});
console.log(s);
showRealStateUsing(s); // ***
});
But, I would suggest using a promise instead of a raw callback, and handling the error case. And if we're going to use a promise, let's use the modern fetch
rather than the old XHR:
function suggestion() {
return fetch('http://localhost:3001/')
.then(response => {
if (!response.ok) {
throw new Error("HTTP status " + response.status);
}
return response.json();
});
}
showPendingState();
suggestion()
.then(showRealStateUsing) // `showRealStateUsing` receives the suggestion as an argument
.catch(showErrorState); // `showErrorState` receives the error as an argument
If you're targeting an environment that supports async
functions (and/or transpiling), we can make that simpler:
async function suggestion() {
const response = await fetch('http://localhost:3001/');
if (!response.ok) {
throw new Error("HTTP status " + response.status);
}
return response.json();
}
// (in an `async` function)
showPendingState();
try {
showRealStateUsing(await suggestion());
} catch (error) {
showErrorState(error);
}