Expressingx
Expressingx

Reputation: 1572

Mongoose array of Schema not saving anything beside id

I'm creating blog for teaching purposes. I want to have tags (optional). The problem is that it is creating new TagSchema but it saves only the _id in the db for the related post and not the name of the tag.

PostSchema

var mongoose = require('mongoose'),
Comment = require('./Comment'),
Tags = require('./Tag');

var PostSchema = new mongoose.Schema({
  Author: String,
  Title: String,
  Description: String,
  Comments: [{
    type: mongoose.Schema.Types.ObjectId, ref: 'Comment'   
  }],
  Tags: [{
    type: mongoose.Schema.Types.ObjectId, ref: 'Tag'
  }],
  CreatedOn: Date,
  LastEditOn: Date
});

mongoose.model('Post', PostSchema);

module.exports = mongoose.model('Post');

TagSchema

var mongoose = require('mongoose');

var TagSchema = new mongoose.Schema({
  TagName: String
});

module.exports = mongoose.model('Tag', TagSchema);

And in the post request

app.post('/post-add', isLogged, (req, res) => {
    // save new post
    var post = new Post();

    post.Author = req.user.username;
    post.Description = req.body.Description;
    post.Title = req.body.Title;
    post.CreatedOn = new Date();

    if (req.body.Tag.length > 0) {
        var tags = req.body.Tag.split(' ');

        tags.forEach((element, idx) => {    
            var tag = new Tag();
            tag.TagName = element;

            post.Tags.push(tag);
        });
    }

    post.save((err) => {
        if (err) return err;

        res.redirect('/');
    });
});

What am I missing?

Upvotes: 0

Views: 47

Answers (1)

HRK44
HRK44

Reputation: 2742

There are multiple ways to do it, depends on what you actually want.

If you don't need the generated _id for a Tag, you can set up your Tag model as :

var mongoose = require('mongoose');

var TagSchema = new mongoose.Schema({
  _id: String
});

module.exports = mongoose.model('Tag', TagSchema);

This avoids creating duplicated tags.

If you still need an unique _id, then you need to create the tag first and save it :

var tag = new Tag();
tag.TagName = element;
await tag.save();

I would use .findOneAndUpdate() with an .upsert() instead of always creating a new Tag() in this case. Then when you get the Post, use .populate('Tags') to get the tag names.

Upvotes: 1

Related Questions