0

I have a variable called isHome set to false initially. Then I have a couple of functions to comeHome and greetMother that should execute depending on whether isHome is true or false.

After comeHome is called (because isHome = false ) it sets isHome to true. But how come the greetMother() isn't being called afterwards?

It would be nice to get an in-depth explanation for why I can't (programmatically) greet my mother :/

(Note: I don't have much exp with JS, this is my first SO question, and apologies in advance if I created a duplicate Q)

The code:

  let isHome = false;

  const comeHome = () => {
    isHome = true;
    console.log("Going home now");
  };

  const greetMother = () => {
    console.log("Hi Mom!");
  };

  if (isHome === false) {
    setTimeout(() => {
      comeHome();
    }, 2000);
  }

// console.log(isHome) here returns false

  if (isHome === true) {
    greetMother();
  }

The output, and expected outcome

"Going home now"

I console-logged isHome on that line, and it still returns false even though comHome() sets it to true. My assumption is that JS can update global variables from inside functions without needing to use return , so this problem is unexpected for me.

What I tried:

  • I tried swapping the conditionals (true first, false second)

  • Tried using if..else if.. statements

  • Tried wrapping the whole code inside a function, then running that one function

  • Tried the object oriented approach, but same result.

class AppObj {
  constructor() {
    this.isHome = false;
  }

  comeHome() {
    this.isHome = true;
    console.log("Going home now");
  }

  greetMother() {
    console.log("Hi Mom!");
  }

  run() {
    if (this.isHome === false) {
      setTimeout(() => {
        this.comeHome();
      }, 2000);
    }
    if (this.isHome === true) {
      this.greetMother();
    }
  }
}

const appObj = new AppObj();
appObj.run() 
webdevnoob
  • 11
  • 1
  • Are you familiar with what `setTimeout` does? – David Jan 05 '23 at 15:10
  • Yes, that's just a fun bit to add so the console logs appear one after the other (not simultaneously). Unless that's actually the thing that causes the issue? – webdevnoob Jan 05 '23 at 15:11
  • 2
    *"that's just a fun bit"* - Well, no, it does a specific thing. Don't just add random code "for fun". It's important to understand what it does and why you want to use it. `setTimeout` schedules an operation to happen **at a later time**. In this case after 2 seconds. So you shouldn't really expect the variable to be updated immediately when you explicitly told it to update 2 seconds in the future. – David Jan 05 '23 at 15:12
  • Yep, it's causing the issue. But see, this function is necessary. The code in question is a dumbed down version of what I'm trying to achieve. So, can we solve this WITHOUT removing the setTimeout() please? – webdevnoob Jan 05 '23 at 15:13
  • Solve *what*, exactly? What are you trying to do? The current code does exactly what it's written to do. At best it looks like an academic exercise designed to illustrate what `setTimeout` does. – David Jan 05 '23 at 15:14
  • 1
    @webdevnoob: Perhaps you want to wrap your `if (this.isHome === true)` block in another `setTimeout` so it happens *more than 2 seconds* later? – David Jan 05 '23 at 15:18
  • Just so you're clear on the order of things here: 1) First you check if isHome is false | 2) Since isHome is false at this point, you call comeHome() after a delay of 2 seconds | 3) You then check if comeHome is true (which it is not at this point since 2 seconds haven't passed | 4) Now that 2 seconds have passed the call to comeHome is pushed to the call stack, you set isHome to true and output "Going home now" to the console – Adam Pearson Jan 05 '23 at 15:22
  • It's possible to read a little harshness in tone here. Hope the OP isn't put off. The problem I see in the logic is this: if the object has distinct states of not-being-home, coming-home, and being-home, then it's a bug to set `isHome = true` while the object isn't yet home. – danh Jan 05 '23 at 15:22
  • 1
    @danh I mentally prepared for this :) Redoing my (actual) code tomorrow, will post another question soon. – webdevnoob Jan 05 '23 at 15:39
  • @David thanks mate, I actually learned something. Have a good one – webdevnoob Jan 05 '23 at 15:39
  • @AdamPearson explained it well, thank you – webdevnoob Jan 05 '23 at 15:42
  • Your code and expected behaviour works. However the commented `console.log` you have confusion about `isHome` still being `false` happens because [`setTimeout()` is an asynchronous function, meaning that the timer function will not pause execution of other functions in the functions stack](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout). – Aleksandar Jan 05 '23 at 16:48

0 Answers0