Return list of saved items using populate() in Mongoose

Viewed 60

I am trying to create a page displaying saved items per user, so far my view is showing the JSON string, I want to render the original document (image, title, date,..) Trying to understand populate() better. Thanks

In DB

  {
    "_id":{"$oid":"6089d131efbe7e3e0c5c51f3"},
    "joinDate":{"$date":"2021-04-28T21:17:06.928Z"},
    "name":"...",
    "email":"...",
    "password":"...",
    "createdAt":{"$date":"2021-04-28T21:18:41.832Z"},
    "updatedAt":{"$date":"2021-04-28T21:18:41.832Z"},
    "__v":0,
    "avatar":"18756.png",
    "savedArticles":[
    "5eb91189c2de0f24fc1517db", // >> ObjectId of original
    "585ad7294a91aa0de83d8ac4"
    ]}

My function:

router.get('/savedItems/:id/', checkAuthenticated, (req, res) => {
  const id = req.params.id;
  mongoose.model('Users').find({
    _id: id
   })
   .populate('savedArticles', 'title')
   .exec(function(err, results) {
       if (err) {
        console.log(err)
           return;
       }
       res.render('savedItems.ejs', { savedArticles: results, user: req.user })
       console.log( JSON.stringify(results))
   });
})

Models:

var Schema = mongoose.Schema;
var userSchema = new Schema({
// ...
    savedArticles:[{type: Schema.Types.ObjectId, ref: 'Article' }]
},{ autoCreate: true})

var Schema = mongoose.Schema;
var articleSchema = new Schema({
    title:  { type: String, required: true },
 //...
  
})
const Users = mongoose.model('Users', userSchema)
const Article = mongoose.model('Article', articleSchema)

In view:

        <% for(i=0; i < savedArticles.length; i++) {%>
                <a href='#'><%= savedArticles[i].savedArticles %></a>
                <% } %>
        

Output:

    { _id: 5eb91189c2de0f24fc1517db, title: 'Gatsby' },  
{ _id: 585ad7294a91aa0de83d8ac4, title: 'Blade runner' }

Output Update with objects

{
  _id: ...,
  name: '',
  email: '',
  password: '....',
  savedArticles: [
    {
      _id: ...,
      title: '...',
      director: '...',
      year: '...'
    },
    {
     _id: ...,
      title: '...',
      director: '...',
      year: '...'
    }
  ],
}
1 Answers

When you do populate, then mongoose will based on the _ids that are stored in savedArticles array go and fetch from the Articles collection documents with those _ids and it will change _ids in savedArticles array with actual documents. So, when your frontend got the result, savedArticles array will be array of objects (documents from Articles collection) and not array of _ids. Now you can iterate over that array and access specific field of each article, like: savedArticles[0].title.

Related