Comparison of two tables in Javascript for different values

advertisements

Javascript gurus, I need your help.

I need to compare two different arrays and check for different values. The values are coming from the same form multi select element. I tried getting a list of current values (cacheTermList) and checking for new value on change (newTermList). The idea is I want to pass an id to an ajax call if a new value was input, and return some data to the screen.

Code:

var cachedTermList = $('select#edit-categories').val();

      if (cachedTermList == null) {
        var cachedTermList = new Array();
      }

      $('select#edit-categories').chosen().change(function() {
        var newTermList = $('select#edit-categories').val();

        if (cachedTermList != null) {
          for(var i = 0; i < newTermList.length; i++) {
          alert(newTermList[i]);
            if (!($.inArray(newTermList[i], cachedTermList))) {
              $.ajax({
                 type: "GET",
                 url: "/classifieds/js/term/" + newTermList[i],
                 success: function(data){
                   //$('div#term-help-text').html(data);
                   cachedTermList.push(newTermList[i]);
                   alert(cachedTermList);
                 }
               });
            }
          }
        } else {

        }
      });

Bear with me, I don't tend to work with Javascript too often. I was trying to get a current list of values by setting cachedTermList on load, then when the select changes, set a newTermList to the new value of the field, then loop it, and check for a value in that list that is not in the cached list.

While I could see things happen, and dump both term lists and see different values, for the life of me I could not get it to push the found value to the cached list so that the next time the element changes, it doesn't keep sending the same value to the ajax call again and again. After the .push() executes, it just adds ',,,' without values. Where am I going wrong?


It is the typical closure - loop problem. All success callbacks reference the same i. At the time the callbacks are executed, the loop already finished and i will have the value newTermList.length + 1, so newTermList[i] will return undefined.

You have to capture the index or the value by introducing a new scope, which can be done by calling a function (JavaScript has no block scope).

Update: Another problem is that $.inArray does not return a boolean value, but the index of the element or -1. So you have to compare the return value against -1.

$('select#edit-categories').chosen().change(function() {
    // ...
    for(var i = 0; i < newTermList.length; i++) {
        if ($.inArray(newTermList[i], cachedTermList) === -1) {
            addTerm(newTermList[i], cachedTermList);
        }
    }
    //...
});

function addTerm(term, target) {
    $.ajax({
        type: "GET",
        url: "/classifieds/js/term/" + term,
        success: function(data){
            //$('div#term-help-text').html(data);
            target.push(term);
            alert(target);
        }
    });
}

Also keep in mind that all Ajax calls will basically be executed at the same time. The loop does not wait until one call finished. If you want to execute the calls one at a time, you can use jQuery's Deferred objects.