4

I'm trying building an application using MongoDB, Mongoose, JQuery, and Node.js. Whenever I try to add to an array within my Schema sometimes it will add that item several times.

Schema

This is my schema, I'm trying to add the my upvote and downvote arrays that keep track of users that voted by their id.

    var SuggestionSchema = new mongoose.Schema({
      title: String,
      content: String,
      link: String,
      upvote: [{
        user_id: {
        type: Schema.ObjectId,
        ref: 'User'
        }
      }],
      downvote: [{
        user_id: {
        type: Schema.ObjectId,
        ref: 'User'
        }
      }],
      user_id: {
        type: Schema.ObjectId,
        ref: 'User'
      },
      category_id: {
        type: Schema.ObjectId,
        ref: 'Category'
      },
    });

Route and Query

Here is my put route and query

    router.put('/:suggestion_id/downvote', function(req, res, next) {
      Suggestion.findByIdAndUpdate(
      req.params.suggestion_id,
      {$push: {"downvote": req.body}},
      function(err, suggestion) {
        res.json(suggestion);
      })
    });

Ajax Call with Jquery

This is my PUT request that is triggered on a click.

$('#downvote').click(function(){
    
    var user = {
        user_id: current_user._id
    }

    $.ajax({
        url: current_url + "suggestions/" + current_suggestion + '/downvote',
        type: 'PUT',
        data: user,
        success: function(data){
            //callback
        }
    });         

}

Results

Two other things to note:

The console will return:

Failed to load resource: net::ERR_EMPTY_RESPONSE

AND

Ultimately just clicking once sometimes results in 2 or 3 of the same user being pushed into the downvote array in the Schema. I put some safeguards on the front end that checks if the user has already voted, but it still seems to put through multiple times so I think it's a different issue. I believe I'm just approaching it wrong or missing something fundamental. I've only been coding for 6 months so I'm still learning. Thanks!

1
  • And do you see multiple requests happening against the server when this happens? Commented May 21, 2015 at 3:59

1 Answer 1

1

Instead of using the $push operator to push the user id object to the downvote array, use the $addToSet operator. This adds a value to an array unless the value is already present, in which case $addToSet does nothing to that array. It only ensures that there are no duplicate items added to the set and does not affect existing duplicate elements. If the field is absent in the document to update, $addToSet creates the array field with the specified value as its element. So you final route will look like:

router.put('/:suggestion_id/downvote', function(req, res, next) {
    Suggestion.findByIdAndUpdate(
        req.params.suggestion_id,
        {$addToSet: {"downvote": req.body}},
        function(err, suggestion) {
            res.json(suggestion);
        }
    );
});
Sign up to request clarification or add additional context in comments.

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.