1

I want to check, if a user is already in my database (sqlite3).

  • If the user exists: return 500 (ERROR!!)
  • If the user not exists: return 200 (ok)

Thats my script: node.js+express on serverside.

app.post('/adduser', function(req,res){
    db.serialize(function(){
        var user = req.body.user;
        var password = req.body.password;
        var err = false;

        db.each("SELECT name FROM users", function(err, row) {
            if (user == row.name) {
                console.log(row.name);
                err = true;
                console.log("a: " +err);
                res.send(500);
                return false;
            }
        });

        if (err==false) {
            console.log("b: " +err);
            res.send(200);
        }

    })
});

I get always the success code 200 regardless of whether I submitting an existing username or not. Thats the log from server:

b: false
testuser
a: true

I've entered an exisiting user, but it got code 200. Strange, I get b before a.

6
  • Javascript isn't compiled it is ran, it isn't converted into anything, so the word "compile" is incorrect. Commented Dec 21, 2013 at 18:59
  • Why would you return 500 (internal server error) if the user exists. Commented Dec 21, 2013 at 18:59
  • db.each doesn't (since it takes a callback) seem to run synchronously, so your if(err==false) line will execute long before getting the first result from the database. Commented Dec 21, 2013 at 19:04
  • err is the database error, rather than record not found. Amend your first if instead. Commented Dec 21, 2013 at 19:13
  • I want to notify my client, that the user is already in my database and it can't be added. Therefore I use the 500 code Commented Dec 21, 2013 at 19:19

2 Answers 2

2

Your database queries are called asynchronously. Even if you specify db.serialize, which will cause sqlite to run its sql-queries in the order you specified, the DB query is detached.

This means that the response from the DB (your anonymous callback function in "db.each ...") is called when a result is received.

However, the program is run further, calling your "if (err==false) ..." first.

For example:

    var err = false; // called first

    db.each("SELECT name FROM users", function(err, row) {
       // called 3rd (after result from DB/disk)
    });

    if (err==false) {
       // called second
    }

The db.each() function also accepts a third parameter (see API Documentation), to be called when all queries have finished. According to this, your code should look like:

app.post('/adduser', function(req,res){
  db.serialize(function(){
    var user = req.body.user;
    var password = req.body.password;
    var err = false;

    db.each("SELECT name FROM users", function(err, row) {
        if (user == row.name) {
            console.log(row.name);
            err = true;
            console.log("a: " +err);
            res.send(500);
            return false;
        }
    }, function() {
        if (err==false) {
            console.log("b: " +err);
            res.send(200);
        }
    });
  })
});

When coding node.js, you should always keep in mind that any disk/io/net/db/etc. is called async and the code in the callback will be executed after the following code.

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

1 Comment

Thanks for your answer. I will vote up your answer, if I have enough reputation
0

The 'each' function will call back asynchronously with each of the rows in the result set. You can add a completion handler as a final argument that will be called once all rows have been returned.

db.each("SELECT name FROM users", function(dberr, row) {
    if (user == row.name) {
        console.log(row.name);
        err = true;
        console.log("a: " +err);
        res.send(500);
         return false;
    }
}, function() { // Completion Handler
    if (err==false) {
        console.log("b: " +err);
        res.send(200);
    }
});

NOTE: I've also modified the first argument to your first callback function so that there is no scope confusion.

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.