Calling vs. Referencing in JS first appeared on Medium.
For my JavaScript API / Rails back-end project at Flatiron School, I decided to create an app called Interviewr that gives new interviewers the tools (read: questions) they need to conduct a great interview. As an HR Business Partner, I see the need for this kind of app every day, and as a new coder, I felt it was time I built something that solved a real problem.
As with most projects, I got stuck on things such as:
- Typos
- Forgetting to seed my database
- Not having a JSON reader installed on Chrome
- Calling functions
My 24-hour problem was calling functions-related and it threw an ‘Uncaught Reference Error.’ But, why?!
Here was the (very messy) code in my questions.js file:
newQuestion() {
var randomNumber = Math.floor(Math.random() * (this.questions.length - 1));
if (randomNumber > this.questions.length - 1) {
alert("You've seen all questions!");
done = true;
} else {
document.getElementById('questionDisplay').innerHTML
= this.questions[randomNumber].content;
}
document.getElementById("next").addEventListener("click", function(e) {
newQuestion();
});
}
}
Something did NOT like this line:
document.getElementById("next").addEventListener("click", function(e) { newQuestion(); });
The error stated that newQuestion hadn’t been defined at the time it reached the click.
Do you see the problem? It’s the ol’ parentheses. These little guys call a function rather than referencing it. I didn’t just reference newQuestion for later use within the eventListener, I called it in my function. This executes the function where it shouldn’t be executed. So, no. It hadn’t been defined by the time it reached the click.
I went in and refactored my code (a lot) to the following. Suddenly things were working:
fetchAndLoadQuestions(){
this.adapter
.getQuestions()
.then(questions => {
questions.forEach(question => this.questions.push(new Question(question)))
})
.then(() => {
this.newQuestion()
})
}
initBindingsAndEventListeners() {
this.btn = document.getElementById("next")
this.btn.addEventListener("click", this.newQuestion.bind(this))
}
newQuestion() {
var randomNumber = Math.floor(Math.random() * (this.questions.length - 1));
document.getElementById('questionDisplay').innerHTML = this.questions[randomNumber].questionHtml();
}
Within my initBindingsAndEventListeners, I reference newQuestion, which is expected to execute upon a click. The only place I call newQuestion is when I fetch and load my Questions.
Another way to think about it:
- Calling/newQuestion(), I need this to run now!
- Referencing/newQuestion, I’m referencing this now, so it can be called later.
One of my favorite things about coding is getting past an error (even if it means getting to a new error). In these moments, you realize how much you don’t know and it can feel pretty crummy — but, stay positive! I talk to Senior Developers who tell me they spend a lot of time Googling and still miss typos in their code. Stories like this keep me going. After all, a classmate told me that the concept of calling vs. referencing is a common JavaScript newbie blindspot…and I’ll take his word for it.
Top comments (1)
Rarely was there ever a more appropriate header image. 😁