-1

I am well aware that this question has been asked a million and one times, however I've tried every suggested solution, and none of them have worked.

I think what I'm trying to do is have a callback that's a closure, but every way I try to do this either ends with the parameter in the callback being "undefined" or the callback getting called too early.

var pages = ["why", "ux", "examples", "make", "marketplace"]
for (i = 0; i < 5; i++) {
    alert("pages is" + pages[i])
    if (filesadded.indexOf("[" + pages[i] + "]") == -1) {
        function fas2(callback) {

            var scriptadded = document.createElement('script')
            scriptadded.setAttribute("type", "text/javascript")
            //Date.now() is added to the end of the filename so that if the main page is reloaded, the other pages will update if in cache
            scriptadded.setAttribute("src", pages[i] + ".js?" + Date.now())

            scriptadded.onload = callback(pages[i]);
            scriptadded.onreadystatechange = callback(pages[i]);

            //adds line to head
            document.getElementsByTagName("head")[0].appendChild(scriptadded)
        }
        //adds file name to list of loaded files
        filesadded += "[" + pages[i] + "]"

        var addPage2 = function (toSwitch) {

            switch (toSwitch) {
                case "why":
                    why.addPage()
                    break;

            }
        }

        fas2(addPage2);
    }
}

In the version shown above, the callback gets called too early and I get the error "Can't find variable: why." Alternatively, when I have something like scriptadded.onload = function() {callback(pages[i])}; the callback gets called at the correct time, but toSwitch ends up being undefined

Joseph
  • 466
  • 1
  • 6
  • 15
  • Possible duplicate - http://stackoverflow.com/questions/1190642/how-can-i-pass-a-parameter-to-a-settimeout-callback although there are other techniques you could use, e.g. `Function.prototype.bind` – Sacho May 05 '15 at 08:50
  • The specific version you've posted seems to be suffering from formatting issues - for example, the closing brace for `fas2` is lined up with the `if (filesadded...)` statement, which is closed on the last line instead(and the `for` statement is never closed) – Sacho May 05 '15 at 08:53
  • The formatting should be fixed now. The issues arose from me pasting it into Stack Overflow and don't exist in my actual code. – Joseph May 05 '15 at 13:42
  • The answer in http://stackoverflow.com/questions/1190642/how-can-i-pass-a-parameter-to-a-settimeout-callback does not work for my code. When I try `fas2(function() {addPage2(pages[i]);});` I get undefined – Joseph May 05 '15 at 13:52

1 Answers1

0

So I figured out my problem...

The issue appears to be that because it was a closure, pages[i] was staying alive after the function finished (when the callbacks were called), but it was always set to it's final value (pages[5] == UNDEFINED). In other words, the variable being passed into the callback, not its value. The only way I was able to get it to work was to declare the callback with a set value each time.

            var testHolder = pages[i]
            alert("testHolder is" + testHolder)
            switch(testHolder)
            {
            case "why":
                fas2(function() {addPage2("why");});
                break;
            case "ux":
                fas2(function() {addPage2("ux");});
                break;
            case "marketplace":
                fas2(function() {addPage2("marketplace");});
                break;
            case "make":
                fas2(function() {addPage2("make");});
                break;
            case "examples":
                fas2(function() {addPage2("examples");});
                break;
            }

Although this is messy, it works for my code, where I'm iterating over a pre-defined set of values. However, others may not be so lucky, so it may be helpful if someone can find a better solution.

Edit: A better solution can be found JavaScript closure inside loops – simple practical example

I am not marking my question as a duplicate because the above answer is not specifically for the case of callbacks.

Community
  • 1
  • 1
Joseph
  • 466
  • 1
  • 6
  • 15