Pregunta

This script is part of a chrome extension that will loop through a table, look for a match, and send a message back to a background script. Here is the script (content script):

function resolveMulti(city){
  counter = 1;
  results = "";
  resultsArray = $("iFrame").contents().find("#table tr[id*='row'] td:nth-child(13)");
  resultsArray.each(function(index){
    if($(this).html().toLowerCase() == city.toLowerCase()){
      results = "Found";
    }
    else if(counter == resultsArray.length){
      results = "No City Match Found";
    }
    counter++;
  });
  return results;
}

The function is returning prior to the $.each loop finishing. Since 'results' isn't defined until the $.each loop is evaluated, the browser raises an error that 'results' hasn't been defined. How can I return the correct results from this function?

¿Fue útil?

Solución

First your questions, then some notes about several issues in that code.

The function is returning prior to the $.each loop finishing.

No, it isn't. It may be raising an exception, which is similar but different.

Since 'results' isn't defined until the $.each loop is evaluated, the browser raises an error that 'results' hasn't been defined. How can I return the correct results from this function?

By declaring the variable. You need a var results in the function:

function resolveMulti(city){
  var results; // <=========== Here
  counter = 1;
  resultsArray = $("iFrame").contents().find("#table tr[id*='row'] td:nth-child(13)");
  resultsArray.each(function(index){
    if($(this).html().toLowerCase() == city.toLowerCase()){
      results = "Found";
    }
    else if(counter == resultsArray.length){
      results = "No City Match Found";
    }
    counter++;
  });
  return results;
}

Without one, in loose mode you're falling prey to The Horror of Implicit Globals (in strict mode, it would be an error). But the Horror of Implicit Globals only works for setting; if it happens that there are no matches for that jQuery selector, you'll never set anything, and so never create the global, and your return will try to read the value of an undefined symbol, which will cause a ReferenceError even in loose mode.

It's hard to tell from the snippet shown, but you may well have other undeclared variables in there (counter and resultsArray) that you want to declare with var.

But there's another issue: Your results variable will have the result from the last iteration of the each loop, overwriting any value from a previous iteration. And if there are no matching elements at all, it will never have a value. I suspect you wanted something like this:

function resolveMulti(city){
  var results = "No City Match Found";
  var resultsArray = $("iFrame").contents().find("#table tr[id*='row'] td:nth-child(13)");
  resultsArray.each(function(index){
    if($(this).html().toLowerCase() == city.toLowerCase()){
      results = "Found";
      return false; // <== Stops the `each` loop
    }
  });
  return results;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top