1

in the following code, why does postCodes[i].countryCode return the last value in the loop, and not the current value in the loop? and how can i return the current value in the loop?

for (var i = 0; i < postCodes.length; i++) {
    for (var ind = 0; ind < salesSuite.Defaults.Countries.length; ind++) {
        if (postCodes[i].countryCode == myNamespace.Countries[ind].code) {
            $('<button/>')
                .click(function () {
                    console.log(postCodes[i].countryCode);
                })
                .appendTo($modalContent);
3
  • see here stackoverflow.com/questions/750486/… Commented Dec 6, 2013 at 21:05
  • seen that, i still dont get it. If i add console.log(postCodes[i].countryCode) just after the if it returns the value, can someone explain what is happening here, and why? Commented Dec 6, 2013 at 21:07
  • This is a classic example of closures within a loop - read up here: stackoverflow.com/a/750506/448865 Commented Dec 6, 2013 at 21:13

1 Answer 1

2

Try adding a function that gets a handler which creates a local variable to hold that postCode. And of course the reason for this is the usage of shared variable i inside the handler which would have run out by the time the handler is invoked So ultimately in your handler you are trying to invoke postCodes[postCodes.length].countryCode which is same as undefined.countryCode and will throw an error..

$('<button/>')
     .click(getHandler(postCodes[i]))
     .appendTo($modalContent);
.....
.....

function getHandler(postCode){ 
// This function creates a closure variable postCode which will hold that particular postCode passed in for each invocation to be used in the function reference returned by this
  return function () {
        console.log(postCode.countryCode);
   }
}

Demo

Instead of doing all this you can utilize jquery data api to hold the postCode.

  $('<button/>')
            .click(function () {
                console.log($(this).data('postCode').countryCode);
            })
            .appendTo($modalContent).data('postCode', postCodes[i]);

Demo

Sign up to request clarification or add additional context in comments.

12 Comments

i am looking for an explanation also, could you explain this? Why does it happen?
@Dementic Yes of course (You can read the ) by the time your handler executes on click out the value of i will be incremented to the last value. so it will always be undefined.countrycode since postCodes[postCodes.length+1] is undefined.
nice way to create a closure
@A.Wolff Infact OP can use data api itself instead of complicating this much i believe.
@Dementic That is what you will have. You will have a postCode in your handler. Did you even try to apply this?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.