Reputation: 27
I'm trying to call a JavaScript function (apiCall) using an event listener binded to a drop-down list listening for a change.
I want the function to re-run when a different menu item is selected from the drop-down list, but when I run this code, the error occurs on the event listener saying that 'apiCall' is not defined, even though it clearly is right above.
Any suggestions?
Thanks in advance.
// API CALL
var request = new XMLHttpRequest()
request.open('GET', base + forecast + key + city, true)
request.onload = function apiCall() {
var data = JSON.parse(this.response)
console.log(data)
string = JSON.stringify(data, null, 4);
app.innerHTML = string;
}
document.getElementById("locationList").addEventListener("change", apiCall)
//send request
request.send()
Upvotes: 0
Views: 56
Reputation: 50684
The function which you're assigning to window.onload
is a function expression, not a function declaration. A named function expression's name isn't added to the surrounding scope, and so, it is only available locally to the function expression itself. This means you won't be able to reference it later on outside the function:
function iAmAFunctionDeclaration() {
console.log("abc");
}
+function iAmAFunctionExpression() {
console.log("abc");
}
console.log(typeof iAmAFunctionDeclaration);
console.log(typeof iAmAFunctionExpression); // undefined (not added to the `window`).
Instead, if you can make apiCall
a function declaration, you'll be able to access its name to execute it later on, as well as assign it as a callback:
function apiCall() {
console.log("performing api call");
}
window.onload = apiCall;
document.addEventListener("click", apiCall);
In order to make your API call work correctly, you can either .bind()
your request
to your apiCall
function as shown by @Stratubas or you can replace this
keyword with request
. This will allow you to handle what this
refers to within your callback. For more ways of dealing with this
inside of a callback, see this answer and this answer.
You can read more about function expressions here
Upvotes: 2
Reputation: 3067
Writing the function first, then assigning it to request.onload
seems to be working:
var request = {};
function apiCall() {
console.log('hello');
}
request.onload = apiCall;
request.onload();
apiCall();
So your code should be like
// API CALL
var request = new XMLHttpRequest()
request.open('GET', base + forecast + key + city, true)
function apiCall() { // <- removed 'request.onload' from here...
var data = JSON.parse(this.response)
console.log(data)
string = JSON.stringify(data, null, 4);
app.innerHTML = string;
}
request.onload = apiCall; // <- and placed it here
const boundApiCall = apiCall.bind(request); // to keep your 'this' object
document.getElementById("locationList").addEventListener("change", boundApiCall)
//send request
request.send()
Edit: I see you're using this
inside your function. I'm not 100% sure (still learning here), but I think the extra bind
I added will keep your this
working as previously.
Upvotes: 1