0

I've noticed there's little documentation and info about how I should manipulate an array of objects using Mongoosejs.

I have the following model/Schema for an User:

'use strict';

/**
 * Module Dependencies
 */

var bcrypt    = require('bcrypt-nodejs');
var crypto    = require('crypto');
var mongoose  = require('mongoose');

 /**
 * Custom types
 */
var ObjectId = mongoose.Schema.Types.ObjectId;

var userSchema = new mongoose.Schema({

  email: { type: String, unique: true, index: true },
  password: { type: String },
  type: { type: String, default: 'user' },
  facebook: { type: String, unique: true, sparse: true },
  twitter: { type: String, unique: true, sparse: true },
  google: { type: String, unique: true, sparse: true },
  github: { type: String, unique: true, sparse: true },
  tokens: Array,

  profile: {
    name: { type: String, default: '' },
    gender: { type: String, default: '' },
    location: { type: String, default: '' },
    website: { type: String, default: '' },
    picture: { type: String, default: '' },
    phone: {
      work: { type: String, default: '' },
      home: { type: String, default: '' },
      mobile: { type: String, default: '' }
    }
  },

  activity: {
    date_established: { type: Date, default: Date.now },
    last_logon: { type: Date, default: Date.now },
    last_updated: { type: Date }
  },

  resetPasswordToken: { type: String },
  resetPasswordExpires: { type: Date },

  verified: { type: Boolean, default: true },
  verifyToken: { type: String },

  enhancedSecurity: {
    enabled: { type: Boolean, default: false },
    type: { type: String },  // sms or totp
    token: { type: String },
    period: { type: Number },
    sms: { type: String },
    smsExpires: { type: Date }
  },

  friends: [{
    friend: { type: ObjectId, ref: 'User' },
    verified: { type: Boolean, default: false }
  }]

});

/* (...) some functions that aren't necessary to be shown here */

module.exports = mongoose.model('User', userSchema);

So as you can check I defined Friends inside User like this:

  friends: [{
    friend: { type: ObjectId, ref: 'User' },
    verified: { type: Boolean, default: false }
  }]

Now the question is how can I add, edit and delete this array in a Node.js script?

BOTTOMLINE: How can I manipulate arrays that are inside MongoDB Schemas, using Node.js and Mongoose.js? Do I always have to create a Schema function or can I access it directly?

EDIT (13/07/2014): So far I've created a HTTP GET that gives me the array like this:

app.get('/workspace/friends/:userid', passportConf.isAuthenticated, function (req, res) {
  User.find({_id: req.params.userid}, function (err, items) {
      if (err) {
          return (err, null);
      }
      console.log(items[0].friends);
      res.json(items[0].friends);
  });
});

But this only returns an array of friendIds, but what if I want to create some sort of '/workspace/friends/:userid/del/:friendid' POST, or add POST. I can't seem to figure out how I can get this done.

2
  • 1
    You do so as with regular JavaScript objects (push, concat, etc). What have you tried that's not working? Commented Jul 13, 2014 at 17:06
  • Hey @aarosil I made a GET request for the array but how can I edit and save it again? Commented Jul 13, 2014 at 19:09

2 Answers 2

1

You can do something like following

app.get('/workspace/friends/:userid/delete/:friendId', passportConf.isAuthenticated, function (req, res) {
  User.findOne({_id: req.params.userid}, function (err, user) {
      if (err) {
          return (err, null);
      }
      for (var i = 0; i < user.friends.length; i++) {
        if (user.friends[i]._id === req.params.friendId) {
            user.friends = user.friends.splice(i,1)
        }
      }
      user.save(function(err, user, numAffected){
        if (!err )res.json(user)
        res.send('error, couldn\'t save: %s', err)
      })
  });
});

What it says in mongoose docs is that

"The callback will receive three parameters, err if an error occurred, [model] which is the saved [model], and numberAffected which will be 1 when the document was found and updated in the database, otherwise 0.

The fn callback is optional. If no fn is passed and validation fails, the validation error will be emitted on the connection used to create this model."

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

12 Comments

How is this saving the edit? That's what I don't get? Doesn't the save function need a return or something? And for adding I could use what? Verify if exists user.friends.push(...)? and simply save it with user.save?
That's correct, the mongoDB stuff is handled behind scenes when you call save(), the instance of the model will handle appropriately. There is saveral ways to save, check out doc, it's thorough. Also check out the Schema.Types.Mixed, it's a wild free for all!
But what do I save the argument from the anonymous function?
Isn't working... I corrected some minor errors like missing semicolons but it's not working. It's for some reason not entering the if statement to remove the friend connection. Do you have a clue about this?
check that req.params.friendID is coming up as what you expect.
|
0

If you need to manipulate arrays, you should convert these in objects before.

User.findOne({_id: req.params.userid}, function (err, user) {
  if (err) {
      return (err, null);
  }

  var user = user.toObject();

  //... your code, an example =>
  delete user.friends;
  res.json(user);
});

Regards, Nicholls

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.