1

I'm new to MEAN stack. I'm trying to implement this and this. I'm using $pull. But they ain't working maybe because my structure in mongodb is different from theirs. So let me first show you that:

enter image description here

downvoters is an string array that contains userids who downvoted that particular article. Lets say the person on downvoters[2] i.e 53et853rf later upvoted this article.Then his userid should be removed from downvoters list. Here is my code:

api.js

router.put('/update-upvotes', (req, res) => {
  let articleData = req.body;
  ...
  Article.update(
    {articleid: '5p4aqbryi'},
    { $pull: { downvoters: '53et853rf' } }
  );
  Article.findOneAndUpdate(
    {articleid: '5p4aqbryi'},
    {upvotes: articleData.upvotes, upvoters: articleData.upvoters}, useFindAndModify=false,
    (error, user) => {
      if(error) {
        ...
      }
      else {
        ...
      }
    })
   })

But that id is not deleted. There's no error or warning on console. Please correct me.

And here is the schema

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const articleSchema = new Schema({
  articleid: String,
  title: String,
  content: String,
  date: String,
  contributor: String,
  upvotes: Number,
  upvoters: [],
  downvotes: Number,
  downvoters: []
})
module.exports = mongoose.model('article', articleSchema, 'articles');

PS: Let articleId and downvoter id be hardcoded now. I'll make them dynamic later.

mickl
  • 48,568
  • 9
  • 60
  • 89
Tanzeel
  • 4,174
  • 13
  • 57
  • 110

1 Answers1

1

Both upvoters and downvoters are String arrays so your Mongoose schema should look like below:

const articleSchema = new Schema({
    articleid: String,
    title: String,
    content: String,
    date: String,
    contributor: String,
    upvotes: Number,
    upvoters: [String],
    downvotes: Number,
    downvoters: [String]
});

You should also keep in mind that update() is an asynchronous operation which needs to be awaited or handled as Promise so:

let opResult = await Article.update(
    {articleid: '5p4aqbryi'},
    { $pull: { downvoters: '53et853rf' } }
);

or

Article.update(
        { articleid: '5p4aqbryi' },
        { $pull: { downvoters: '53et853rf' } }
    ).then(opResult => console.log(opResult));
mickl
  • 48,568
  • 9
  • 60
  • 89
  • I appreciate your help. But the first solution is giving this error: `SyntaxError: await is only valid in async function`. And the second one had no change at all, nothing happened. – Tanzeel Dec 26 '19 at 21:43
  • 1
    You need to mark your function as async, like: `async () => { await Article.update(...) }` . Besides that I've tested your example and it works so please make sure that you're running your query on the collection where your data resides. Try to make sure that `Article.findOne({ articleId: '5p4aqbryi' })` returns the document you're trying to modify. – mickl Dec 26 '19 at 21:47
  • Yes. everything else is working perfectly in the code. `Article.findOneAndUpdate()` is also working . But I'm afraid I didn't understand "You need to mark your function as async" very well. – Tanzeel Dec 26 '19 at 21:50
  • You can read this: http://thecodebarbarian.com/80-20-guide-to-async-await-in-node.js.html – mickl Dec 26 '19 at 21:52
  • Sir I'm so sorry. My bad. Your second solution is working. But It should be `{ articleid: articleId }`. Just now i see the edit also. – Tanzeel Dec 26 '19 at 21:54
  • 1
    And please make sure that you're "awaiting" the execution of first function. Otherwise `update` and `findOneAndUpdate` may interfere with each other. If you can't use awaits run `findOneAndUpdate` in a callback of `update()` – mickl Dec 26 '19 at 21:54
  • @Tanzeel yep, sorry for that typo :) – mickl Dec 26 '19 at 21:54
  • No problem Sir. :-). thanks for this. Hope this will pas unit test cases as well. Or else I'll come back to you. ;-) – Tanzeel Dec 26 '19 at 21:55
  • 1
    @Tanzeel lesson learned - `update` returns `Promise` which needs to be `await`-ed or the continuation should be run as `.then()` otherwise the operation won't get executed – mickl Dec 26 '19 at 21:56
  • 1
    I'll always remember this. :-). By the way. You an see this: http://fast-depths-77615.herokuapp.com/options. this is what I'm making. – Tanzeel Dec 26 '19 at 21:59