简体   繁体   中英

Comparing two arrays in Javascript for different values

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 .

You are using ajax in a for loop and pushing the newTermList item in its success handler. Since ajax is async by default the loop is not going to wait for the ajax request to get completed. Try to put the pushing code outside the ajax call. But this will not work if the ajax call fails, may be you dont want to add the item into cache when the ajax call fails.

Try something like this

for(var i = 0; i < newTermList.length; i++) {
      alert(newTermList[i]);
        if (!($.inArray(newTermList[i], cachedTermList))) {
          $.ajax({
             type: "GET",
             context: i,//Here I am setting the value of i into context which can be used in the success handler using this keyword
             url: "/classifieds/js/term/" + newTermList[i],
             success: function(data){
               //$('div#term-help-text').html(data);
               cachedTermList.push(newTermList[this]);
               alert(cachedTermList);
             }
           });
        }
      }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM