0

In my mongoose schema I have the following model for storing users:

var UsersSchema = new Schema({
    username: {type: String},
    our_username: {type: String},
    our_display_name: {type: String},
    hashtags: {type: [String]}
}

I want to create an endpoint in node.js that allows user's to update (add/remove) those hashtags, my use case scenario is that when user logs in to my app, I show him all hashtags with a simple get endpoint:

usersRoutes.get('/:username/hashtags/', functions.validateRequestsGET, function(req, res){
    var username = req.params.username;

    var query;

    if(username != undefined) {
        query = User.find({}).where('username').equals(username).select('hashtags -_id');
    }

    query.exec(function(err, hashtags){
        if(err) {
            res.send(err);
            return;
        }

        res.json(hashtags);
    });
});

But how can I create an endpoint that allows user to add/remove hashtags? I tried with this:

usersRoutes.post('/:username/', function (req, res) {
    var username = req.params.username;
    var hashtagsToAdd = req.body.hashtagsToAdd;
    var hashtagsToRemove = req.body.hashtagsToRemove;

    console.log(hashtagsToAdd);
    console.log(hashtagsToRemove);

    User.findOneAndUpdate(
        {username: username},
        {
            $push: {"hashtags": hashtagsToAdd},
            $pull: {"hashtags": hashtagsToRemove},
        },
        {safe: true, upsert: true},
        function(err, user) {
            if(err)
                console.log(err);
                return callback(err);

            res.json(user);
        }
    );

});

and I use it with sending this:

{"hashtagsToRemove":["food"], "hashtagsToAdd":["something"]}

to my endpoint:

http://localhost:3000/users/randomUsername/

but it raises an error:

message: 'Cannot update \'hashtags\' and \'hashtags\' at the same time'

how can I modify my endpoint so that it covers the possibility of adding/removing hashtags?

user3766930
  • 5,629
  • 10
  • 51
  • 104

1 Answers1

1

You're doing a $pull and a $push at the same time on MongoDB, which is not allowed.

You have two possibilities to achieve what you want to do:

Option 1

  1. Get the user (using findOne)
  2. Manually add and remove the hashtags from the user.hashtags attribute
  3. Update the user hashtagsattribute using the $set operator.

Example:

User.findOne({username: username}, function (err, user) {
  user.hashtags = addToArray(user.hashtags, hashtagsToAdd);
  user.hashtags = removeFromArray(user.hashtags, hashtagsToRemove);
  user.save(function (err, updatedUser) {
    console.log('yeepee');
  });
});

addToArray and removeFromArray are left for exercise ;-)

Option 2

You can update the user in sequence: a first request with $push and, in the callback, another with $pull.

Feature request

There is an opened feature request: https://jira.mongodb.org/browse/SERVER-1050 But there is no plan to implement it.

Related issues:

Community
  • 1
  • 1
Pierre-Yves O.
  • 508
  • 3
  • 15