0

I'm attempting to write a simple validation script in Node where error codes are added to an error array when certain validation checks fail. To complicate things, I also have a function called translate which makes a database call and returns the full text associated with an error code (translated into the specified language). In order to achieve this, I'm using the async library.

Unfortunately, the following code always results in an empty array, even when validation should fail. I've confirmed independently that my translate function works. Any ideas why this isn't working?

app.post("/user", function(req, res) {

  var error = [];

  if (req.body.username == "") {
    error.push("username_required");
  }

  if (req.body.password == "") {
    error.push("password_required");
  }

  for (var i = 0; i < error.length; i++) {
    error[i] = function(callback) {
      translate(error[i], req.language, function(text) {
        callback(null, text);
      });
    };
  }

  async.parallel(error, function(error, results) {
    res.send(results);
  });

});

translate = function(code, language, callback) {
  var code = database.escape(code);
  var language = database.escape(language);
  database.query("SELECT content FROM text WHERE language = 'en' AND code = " + code, function(error, row) {
    callback(row[0].content);
  });
}
8
  • This is the infamous closure problem. Javascritp does not have block scope. Commented May 29, 2013 at 0:31
  • I see. Any suggestions on an alternate approach? Commented May 29, 2013 at 0:32
  • Wrap the callback in a function that creates a closure around its parameter. Commented May 29, 2013 at 0:33
  • lostechies.com/derickbailey/2011/12/04/… Commented May 29, 2013 at 0:33
  • Okay, I'm trying to wrap my mind around this. In general, am I thinking about things in the wrong way? Is this something that is common when using Node and JavaScript? Commented May 29, 2013 at 0:54

1 Answer 1

4

As suggested in the comments, async.map did the trick. Here's my final solution:

app.post("/user", function(req, res) {

  var error = [];

  if (!req.body.username) {
    error.push("username_required");
  }

  if (!req.body.password) {
    error.push("password_required");
  }

  async.map(error, function(error, callback) {
    translate(error, req.language, function(text) {
      callback(null, text);
    });
  }, function(error, results) {
    res.send(results);
  });

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

1 Comment

If you can modify translate to call the callback in traditional Node.js style (callback(error, result)), you can make it even shorter: translate(error, req.language, callback);

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.