General question about using functions

while I was working on the JS Calculator project I realized few things are completely clear to me. I am using jQuery so I am inside the $(document).ready function…
then I have few buttons and when I use the clickhandler function I create an array that I want to use OUTSIDE the clickhandler.
But if , for example, I try to console.log this array or if I want to pass it as argument to another function, apparently the array is empty
This is the link to the code
https://codepen.io/ranran212/pen/gOmaMzN?editors=1011

thanks

In the click handler you are referencing arr, which is declared outside of the click handler at the beginning of the document.ready function, so you aren’t technically creating a new array and you can access it anywhere inside the document.ready function.

yes, and that was my intention: create and array filled by the function triggered by clicking buttons
however, if i try to do something with this arr (for example arr.push(21) and then log it, it results an empty array :frowning:

Hello francesca.giammichel,

I noticed you are using isNaN (is Not a Number) in your conditions on variable “selected”.

As you have assinged a text value to selected:

selected = $(this).text();

It will always not be a number.

Try

console.log('what is the type of selected?:', typeof(selected))

I believe it will always be a “string”.

Also the code is checking for AC twice

(selected == "AC")

Hope that helps out

You might find this link interesting too:

oh, yes, the AC check was there twice :stuck_out_tongue:
But regarding the isNaN() function is actually converting strings (containing numbers) to numbers and it works the way i wanted :slight_smile:

let test = "1235";
console.log(isNaN(test));   //false;

https://www.w3schools.com/jsref/jsref_isnan.asp

as I tried to explain the issue is being able to access to the (filled) array outside the clickhandler func :frowning:

PS: yes, i remembered the difference between the == (comparison) and === (strict comparison)

Just to be clear, be careful with isNaN. It doesn’t tell you if something is a number or not, it tells you if it coerces to NaN. Those aren’t exactly the same thing. And, because implicit coercion can behave oddly in JS, it can be dangerous:

console.log(isNaN('123'));
// false
console.log(+'123');
// 123

console.log(isNaN('apple'));
// true
console.log(+'apple');
// NaN

console.log(isNaN(null));
// false
console.log(+null);
// 0

console.log(isNaN(true));
// false
console.log(+true);
// 1

console.log(isNaN(undefined));
// true
console.log(+undefined);
// NaN

console.log(isNaN([]));
// false
console.log(+[]);
// 0

This uses the unary + operator to coerce the values to a number to see what is happening internally.

That may be what you want, but it is a point of confusion for a lot of people that has caused a lot of bugs over the years.

3 Likes

There is no issue here. The array arr is defined in the document ready function and can be used anywhere in that function, including inside the click handler. I think you need to be more specific as to why you think you are not able to access it.

1 Like

yes, that was my expectation but if you try this code you will log and empty array

$(document).ready(function(){
     let selected = "";
    let arr = [];
    let result = 0;
    let temp = "";

    //clickhandler
    $("button").click(function() {
        selected = $(this).text(); 
        arr.push(selected);
      //console.log(arr);
    })
  console.log(arr);       //[]
})

whereas, if you place the console.log(arr) INSIDE the clickhandler function, you log the array

https://codepen.io/ranran212/pen/eYvpJbx?editors=1111

That’s because the console.log() at the bottom is executed immediately after the click handler is set on the button, when arr is still set to [], before you can actually click on the button, so you will see an empty array when it is executed. To see what is in the array after you click on the button you have to add a console.log() inside the click handler. In other words, adding the click handler on the button does not stop the execution of the remaining code in the document ready function. As soon as the handler has been added the console.log() gets executed.

Everything is working as it should here.

2 Likes

I believe Number.isNaN may resolve this problem

ok, that explanation makes things clearere
but how can I solve the issue of using that filled array outside the handler?

There is nothing to solve, you can use it outside the handler. The arr array has function scope in the document ready function, so it can be used anywhere inside of that function.

thank you :slight_smile: i understand what you are pointing out specifically for the application I am working on isNaN() is doing is job

but at the moment the issue is with a strange error , so i would beg to you have a look
https://codepen.io/ranran212/pen/gOmaMzN?editors=1111

probably I am not able to explain myself
yes, i can access the arr outside the clickfunction and yes, i understand the console.log is exectuting ignoring the clickstuff and so prints out an empty array but AFTER i click the button and perform something on it, you won’t see the numbers added when clicking
or, please, show me how to do that

I think you’ll need to be very specific about what buttons you are clicking, what you expect to see, and where you expect to see it.

I just tried your calculator code pen. I clicked the buttons “9”, “*”, “9”, “=” and in the <p> with id display it shows “81”. Now you can’t really see it because the font color you are using is almost the same as the background color. But if you look real close you can see it. I would suggest you make the font color white.

So I’m not sure if I just solved your problem or if you were referring to something else?

I’m old, I’ve got to go to bed now. I’ll be happy to get back to you tomorrow if you have further questions.

do not worry, we will talk tomorrow because the display style was not the issue I am referring to :stuck_out_tongue:
have a nice sleep :slight_smile:

ok, i will try to formulate again the question and will ask you to write the code according to my request (just for an example, i won’t cheat :slight_smile: )
-i have a number declared and initialized (lets say x=21)
-when I click button A, number x is increased
-when I click button B, number x is decreased
-I can chose freely how many time to push button A or B and lets say that
-I then want to use x in a function

what it the way to do that?

PS: my way (not accomplishing my purpose) is

let x = 21;
$(#buttonA).click(function() {
x++;
}
$(#buttonb).click(function() {
x--;
}
function() {
//do something with x (but there x stays 21, no matter if i click the buttons!
}

I modified your code so that it will work as a standalone web page. Go ahead and copy/paste the below code into its own .html file, open it in your browser, open the JS console, and start clicking on the buttons.

<script src="https://code.jquery.com/jquery-3.6.0.slim.min.js"
	integrity="sha256-u7e5khyithlIdTpu22PHhENmPcRdFiHRjhAuHcs05RI="
        crossorigin="anonymous">
</script>

<button id="buttonA">A</button>
<button id="buttonB">B</button>
<button id="showX">Show value of X in console</button>

<script>
  $( document ).ready(function() {
      let x = 21;
  
      $('#buttonA').click(function() {
          x++;
      });

      $('#buttonB').click(function() {
          x--;
      });

      function displayValueX() {
          console.log(`x = ${x}`);
      }

      $('#showX').click(function() {
          displayValueX();
      });
  });
</script>

first of all thank you for your patience
so, from what I understand I can access the updated value of x only through another button, because anything else will be executed disregarding if buttons are clicked and so x value will be the one I initialiezd
is that correct?

It doesn’t have to be a button, (and technically it is the click handler that is accessing x). I just used another button to trigger the printing of the value of x to the console so you could see that a different function was able to access x.

You can access the value of x however you want inside the document ready function because x is declared at the top level of the function and so anything else in that function will also have access to x (that’s how closures work).

Here’s another example that doesn’t require an active trigger to display the value of x. It merely listens for the value of x to change and then prints the new value to the console when it does. Hopefully this is enough to make clear that x is accessible from anywhere in the document ready function no matter how you access it.

<script src="https://code.jquery.com/jquery-3.6.0.slim.min.js"
	integrity="sha256-u7e5khyithlIdTpu22PHhENmPcRdFiHRjhAuHcs05RI="
        crossorigin="anonymous">
</script>

<button id="buttonA">A</button>
<button id="buttonB">B</button>

<script>
  $( document ).ready(function() {
      let x = 21;
  
      $('#buttonA').click(function() {
          x++;
      });

      $('#buttonB').click(function() {
          x--;
      });

      let lastValue = x;
      setInterval(function() {
          if (lastValue !== x) {
              lastValue = x;
              console.log(`value of x change to ${x}`);
          }
      }, 250);
  });
</script>