I'm creating a stopwatch that stops after hearing a clap. My first function creates a flag variable and calls another. When a loud noise is heard, the flag changes from false to true and should return true to the caller function. A conditional if statement should stop the stopwatch. However, my stopwatch does not stop after returning true.

function callStopwatch() {
    var watch = new Stopwatch(timer);
    watch.start();
    var flag = false;
    draw(flag);
    if(flag == true){
        watch.stop();
    }
}

function draw() {
    var vol = mic.getLevel();
    if(vol > 0.2){
        console.log("true"); //created to check whether sound detection is working
        flag = true;
        return flag;
    }
}

console.log returns true to the console when a clap is heard. Therefore, the flag should become true and return as such and evaluate properly in the caller function's if statement. What could I be doing incorrectly? My guess would be not understanding function scope properly.

4 Answers

0
Community On

All you need to do is to update your flag variable in callStopwatch() after calling function draw.

 function callStopwatch() {
 var watch = new Stopwatch(timer);
 watch.start();
 var flag = false;
 flag = draw(flag); // update flag here
 if(flag == true){
    watch.stop();
 }
 }
0
Dhaval Marthak On

Since javascript is async, it won't wait for draw() to return correct value, it will execute your code async, you can try something like this which mentioned under callback.

draw(flag, function(_flag) {
    if (_flag == true) {
      //to stop watch
      console.log("its true");
    } else {
      console.log("it's false")
    }
  });

Furthermore, your draw() should look something like this.

function draw(flag, callback) {
  var vol = 0.1; // approx value try changing it to 0.3 will return true based on condition
  if (vol > 0.2) {
    flag = true;
  }
  callback(flag);
}
0
null On

You are referring different variables in two functions.

You are referring local variable flag in callStopwatch() function.

var flag = false;

now you call draw() function and you are referring global flag here

flag = true;

You set flag to true but that's different variable and won't affect the flag variable in callStopwatch() function

change the code to:

function callStopwatch() {
  var watch = new Stopwatch(timer);
  watch.start();
  var flag = draw(flag);

  if(flag == true){
    watch.stop();
  }
}

function draw() {
  var vol = mic.getLevel();
  if(vol > 0.2){
    console.log("true"); //created to check whether sound detection is working
    return true;
  }
  return false;
}
0
Beri On

First issue is that you are not returning flag value from draw(). You need to remember that flag property has local scope, so inside of draw() function you have a new variable. That is why changing flag property inside draw() function does not affect flag property in callStopwatch

function callStopwatch() {
    var watch = new Stopwatch(timer);
    watch.start();
    if(draw()){
        watch.stop();
    }
}

function draw() {
    let flag = false;
    var vol = mic.getLevel();
    if(vol > 0.2){
        console.log("true"); //created to check whether sound detection is working
        flag = true;
    }
    return flag;
}

Second approach would be to pass a callback to the draw function.

function callStopwatch() {
    var watch = new Stopwatch(timer);
    watch.start();
    draw(function() {watch.stop();});
}

function draw(onCondition) {
    var vol = mic.getLevel();
    if(vol > 0.2){
        console.log("true"); //created to check whether sound detection is working
        onCondition()
    }
}

Now you don't need the flag property at all.