0

I'm building a function that will automatically scan a folder on server start or on folder change. The script will assemble a widgets folder for installed widgets, then concatenate and build a new partial file for inclusion in the front end app.

The script looks like:

concat.readMethodContents = function(concat) {

    var widget;
    for (widget in concat.widgets) {

        var method;
        for (method in concat.widgets[widget]) {

            if (concat.widgets[widget][method].ready) {
                concat.widgets[widget][method].ready = false;

                fs.readFile('./lib/widgets/' + widget + '/methods/' +  concat.widgets[widget][method].handle, 'utf8', function(err, data) {
                    if (err) {
                        console.log(err);
                    } else {

                        concat.widgets[widget][method].contents = data;

                        concat.writeJsPartialFile(concat);
                    }
                });
            }
        }
    }
}

Before this method is called, the concat object looks like:

{
    "widgets": {
        "hello_world": [{
            "handle": "method1.js",
            "ready": true
        }, {
            "handle": "method2.js",
            "ready": true
        }, {
            "handle": "method3.js",
            "ready": true
        }]
    }
}

The problem with the script is that when method is called, it is defined as done because the loop has finished and the async function is running a callback.

How can I encapsulate or otherwise preserve the variable through that part of the operation?

1
  • Welcome to the land of promises. Commented Oct 31, 2014 at 18:22

1 Answer 1

1

I just answered this exact same problem here: Accessing a MongoDB value from a query within a query

You use a self-executing function to wrap your closure to ensure the value doesn't change underneath you due to the loop. Try something like:

concat.readMethodContents = function(concat) {
    var widget;
    for (widget in concat.widgets) {
        var method;
        for (method in concat.widgets[widget]) {
            (function(widgetMethod) {
                if (widgetMethod.ready) {
                    widgetMethod.ready = false;
                    fs.readFile('./lib/widgets/' + widget + '/methods/' +  widgetMethod.handle, 'utf8', function(err, data) {
                        if (err) {
                            console.log(err);
                        } else {
                            widgetMethod.contents = data;
                            concat.writeJsPartialFile(concat);
                        }
                    });
                }
            })(concat.widgets[widget][method]);
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

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.