ialphan
ialphan

Reputation: 1261

Incorrect array value

I have an array (spliced to size 2) that keeps track of what user click (first, last). first and last elements are unique.

I am trying to load content based on what user clicked. The weird thing that is happening is that I don't see the updated array unless I do 2 console.logs. If 1 log is done the array doesn't get updated. I'm guessing this has something to do with array execution/manipulation time.

The way I debug is to a click handler to document and click to see the array value. Any suggestions or tips?

I never had this issue before. Thanks.

    var clicksInfo = [];

    $('#a, #b, #c').on('click', function(e){

    // array: add, splice
    if(jQuery.inArray($(this).attr('id'), clicksInfo) == -1){
        clicksInfo.push($(this).attr('id'));
        if(clicksInfo.length == 2){
          //  might do something
        }else if(clicksInfo.length == 3){
          clicksInfo.splice(0,1);
        }
      }else{
        clicksInfo.splice(0,1);
        clicksInfo.push($(this).attr('id'));      
      }

      if($(this).attr('id') == 'a'){
        //  do stuff.
      }else if($(this).attr('id') == 'b'){  
        //  do stuff.
      }else if($(this).attr('id') == 'c'){
        //  do stuff.
      }
    });


    $(document).on('click', function(){
      console.log('clicksInfo', clicksInfo);
      // console.log('clicksInfo', clicksInfo);
    });

Upvotes: 0

Views: 129

Answers (2)

Ed Bayiates
Ed Bayiates

Reputation: 11230

The problem you are facing is that events that occur are not guaranteed to execute in a specific order. Either click handler could be executed first, though in most browsers your handler for #a, #b, #c would be executed first.

While you could try to use setTimeout to wait long enough to synchronize your data, your code is quite likely to break.

If you want to handle a click in both cases, my recommendation would be to remove the handler for #a, #b, and #c. Use the document click handler only, pass in the event declaration, and then check the ID of the clicked element in your handler to invoke the first code. You are then guaranteed to have updated data before your second block of code runs. Something like this:

var clicksInfo = [];

$(document).on('click', function(e){

    if (e.target.id === "a" || e.target.id === "b" || e.target.id === "c") {
        // array: add, splice
        if (jQuery.inArray(e.target.id, clicksInfo) == -1){
            clicksInfo.push(e.target.id);
            if(clicksInfo.length == 2){
                 //  might do something
            } else if(clicksInfo.length == 3){
                clicksInfo.splice(0,1);
            }
        } else {
             clicksInfo.splice(0,1);
             clicksInfo.push(e.target.id);
        }

      if(e.target.id === 'a'){
        //  do stuff.
      }else if(e.target.id === 'b'){  
        //  do stuff.
      }else if(e.target.id === 'c'){
        //  do stuff.
      }
    }

    console.log('clicksInfo', clicksInfo);
});

JSFiddle here.

Upvotes: 0

adeneo
adeneo

Reputation: 318372

Strings are strings, arrays are arrays, even in a console.log, so when doing :

console.log('clicksInfo', clicksInfo);

thats a string, a comma, and then an array ?

try doing:

console.log('clicksInfo : '+ clicksInfo);

to show the string representation, or to show the array as an object, don't mix it with other strangeness:

console.log(clicksInfo);

Upvotes: 2

Related Questions