0

I have a quick and dirty javascript application that queries JSON data in a loop. Somewhere I've overstepped my knowledge of Javascript and closures and am too far in the muck to troubleshoot myself.

Here's the pattern...I loop through an array on inputs, each time querying JSON and building an array using .push(). Each iteration calls the function for the next element if there is one.

The strange result is that it works where there is a result, but my catch for null result if(!thisResult) is the part that doesn't work - each iteration that invokes this conditional overwrites all the previous such cases. So all the good results stick but all the coerced nulls all overwrite to the latest each time.

    var results = [];

    $("#searchInput").on("input", function(event) {
        var searchTerm = this.value;
        var assys = parseArray(searchTerm);

        sendRequestLoop(assys, 0, function(result){
            var thisResult = result.cic_search[0];

            if (!thisResult){
                thisResult = resultDefault;
                thisResult.pn = result.searchTerm.substring(0,7);
                thisResult.var = result.searchTerm.substring(9,2);
            }

            results.push(thisResult);

            $("#resultsTable")
                .renderTable(resultsTable, results)
            ;

        });
    }
    );

    function sendRequestLoop (assys, i, callback) {
        $.getJSON(cgi_src, {"cic_search": assys[i]}, function (result) {
            callback(result);
            if (i < assys.length) {
                sendRequestLoop(assys, i+1, callback);
            }
        });
    }       

What am I doing wrong here?

UPDATE

The problem is the assignment of each null result to the default object. I guess it's necessary (though I need to read up because I don't understand) to clone the object here. This simple change fixed it...

  thisResult = clone(resultDefault);

Where I got the clone() function from this page http://jsperf.com/cloning-an-object/2

  function clone(obj) {
   var target = {};
   for (var i in obj) {
    if (obj.hasOwnProperty(i)) {
     target[i] = obj[i];
    }
   }
   return target;
  }

I'd still appreciate someone to explain this problem to me.

Cœur
  • 37,241
  • 25
  • 195
  • 267
robisrob
  • 940
  • 12
  • 23
  • Probably `thisResult = resultDefault;` is the problem. Where is `resultDefault` defined? – Bergi Feb 25 '16 at 18:27
  • it is just a global created in initialization to have all the same object properties expected in JSON. If the query has no results the JSON is `{cic_search: []}`. It is all empty strings so I doubt that's the issue as the table updates each query with all the no-result entries changing to the latest each time – robisrob Feb 25 '16 at 18:38
  • what does console.log(thisResult) show when you expect the flow to take the (!thisResult) condition ? have you verified that the condition block is entered? – devlin carnate Feb 25 '16 at 18:39
  • I know it is entered because I see the substrings appear in my table. Only problem is they keep changing for rows already processed – robisrob Feb 25 '16 at 18:41
  • 1
    @robisrob: Yes, that's exactly the problem: it's a global object, and you're referencing and mutating it everywhere. You need to clone it if you want separate instances (or just put the object literal right in your callback) – Bergi Feb 25 '16 at 18:44
  • I was very skeptical but you are right. I don't understand what's gong on though I guess I need to brush up on object references – robisrob Feb 25 '16 at 18:56

0 Answers0