1

I am just creating a simple user login for using MongoDB, Backbone and Node with Express.

I am stuck on querying the database for the user credentials and reliably identifying whether they exist or not.

I'm trying two things here:

// When user posts to the url
app.post('/save/user', function (req, res) {

  // create user object and store email from form
  var user = {
    email : req.body.email
  };

  // in my collection users
  db.collection('users', function (err, collection) {

    // create a variable existence with the value, in lamens terms 'yes it does' or 'no it doesnt'
    var existence = findOne(collection, {
      $query : {email : user.email}
    });

  });
};

// findOne function passing the collection and the query object
function findOne(coll, query) {
  var cursor = coll.find(query).limit(1);
  return cursor.hasNext() ? cursor.next() : null;
}

So this is the first way I've been trying. Thing is, I don't understand why the cursor doesn't have 'next(), hasNext(), findOne(), forEach()' and other methods for javascript environment but only for mongo shell.

My question is, how do I access these methods from in my Node.js app?

The second way I tried it :

// When user posts to the url app.post('/save/user', function (req, res) {

  // create user object and store email from form
  var user = {
    email : req.body.email
  };

  // in my collection users
  db.collection('users', function (err, collection) {

    // Have a look for the email entered
    var query = collection.find({
      $query : {email : user.email}
    }).limit(1);

    // If it's true, then send response
    query.each( function (err, item) {

      // If the item does exists, then send back message and don't insert. Otherwise, insert.
      if(item !== null) {
        console.log('Item does not equal null : ', item);
        res.send('The email : ' + item.email + ' already exists');
      } else {
        console.log('Item does equal null : ', item);
        collection.insert(user);
        res.send('New user with email : ' + user.email + ' was saved');
      }

    });

  });
};

The problem with this is, it's always going to return null at some point and so I am going to warn the user 'it already exists' and then the next time will be null so it's going to save the email.

I think i'm missing the point so a point in the right direction would be great.

Many thanks in advance!


Well i've looked into a solution but still must be missing the point.

I'm doing an insert, passing in my user object with safe : true but although multiple user objects can be entered, it's still only looking for identical ID;s. I've tried creating an id with new ObjectID() but I still don't understand if a user enters their email adress, thenattempts to create a new user with the same email, it would create a new id for that entry.

By doing the findOne, I can see if it exists easily, Idon't see how it can be done with insert.

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

// Store user details in object
var user = {
  username : req.body.user,
  email : req.body.email,
  password : req.body.password
};

db.collection('users', function (err, collection) {

  collection.insert(user, {safe : true}, function (err, doc) {

    console.log('what is doc : ', doc);
    if(!err) {
      res.writeHead(200, {
        "Content-Type" : "text/plain",
        "Message" : "New user added",
        "Access-Control-Allow-Origin" : "*"
      });
    } else {
      console.log('Error is : ', err);
      res.writeHead(200, {
        "Content-Type" : "text/plain",
        "Message" : "User already exists",
        "Access-Control-Allow-Origin" : "*"
      });
    }

    res.end();

  });

});

});

2
  • Which module are you using to access MongoDB (there are several of them available)? Commented Jul 8, 2012 at 22:18
  • Well i'm using Express right now but by the next answer I haven't been looking through the Native Node.js MongoDB driver. This looks just the ticket Commented Jul 9, 2012 at 15:03

1 Answer 1

3

If you're using the Native Node.JS MongoDB driver, there is a collection.findOne() method and cursors do have nextObject() and each() methods equivalent to the shell methods hasNext() and forEach(). The implementation/naming of the mongo shell equivalents can vary slightly between drivers but you should be able to translate mongo shell examples into Node.JS.

As far as saving a new user goes .. instead of querying for the user before inserting, you would be better to add a unique index on the email field and insert into the collection with safe:true. You can then handle the err result if the insert fails due to a duplicate email. If you do a query before insert there is a potential race condition where the email might not exist when you check for it, but does exist by the time you do the insert.

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

2 Comments

Cool thanks for clearing that up. I am new to Node.js and didn't realise there was the Node.js MongoDB driver API document which I intend to use. That's perfect. For the second part. MongoDB creates a unique ID already. Is it this your referring to? I'll have a go tonight then put the answer up here hopefully so others can learn too. thanks
@WillFalkowski: To be clear on the uniqueness aspect: you need to add a unique index on a field like email. If you try to insert another document with the same indexed value, the second document will not be saved. You need to insert with safe:true so that the insert returns an error if one occurs (such as "duplicate key"). If you don't use safe:true, the insert is treated as "fire and forget" and silently ignored. See getLastError in the MongoDB documentation.

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.