malcoauri malcoauri - 3 months ago 15x
Node.js Question

JS closures with deep nesting

There is the following code of NPM module:

var actions = {};
var methods = ['POST', 'GET', 'PATCH', 'DELETE'];

methods.forEach(function(method) {
actions['mock' + method] = function(browser, url, response) {
browser.execute(function() {
result[method][url] = response;

module.exports = actions;

I want to have 4 methods: mockPOST, mockGET, mockDELETE, mockPATCH. Each method should just execute
with callback function and put
in the appropriate
field -
in the
and so on. But when I execute

utils.mockPOST(browser, 'auth', {"result": "OK"});

I get
method is not defined
error. What should I do? Thanks!


As I see you are using selenium or webdriver for node.js. That makes things a littlebit tricky. You cannot use closures in the browser.execute function, and the reason is it does not run there at all. Webdriver will convert the function to a string, will transfer it to the browser, and will eval that string inside the browser. The nodejs closure is not transferred to the browser, only the function code as a string.

I assume the result object is defined globally inside the browser already.

So what can you do about it? I always recommend not to put function literals inside browser.execute and browser.executeAsync as they are confusing. You can put there a string instead, which will be evaluated. Try the following:

methods.forEach(function(method) {
  actions['mock' + method] = function(browser, url, response) {
    var browserAction = "result[" + JSON.stringify(method) + "]" +
        "[" + JSON.stringify(url) + "] = " +
        JSON.stringify(response) + ";";