Kimkykie
Kimkykie

Reputation: 49

Save multiple instances of an embedded document to my model using mongoose

I am trying to save multiple instances of an embedded document in my model and I am expecting that every time I fill my form data, a new instance of the embedded document is created and pushed into an array.

This is my Prediction schema.

const mongoose = require('mongoose');
mongoose.Promise = global.Promise;

const slug = require('slugs');

const teamSchema = new mongoose.Schema({
  team1: {
    type: String
  },
  team2: {
    type: String
  },
  prediction:{
    type: String
  }
});

const predictionSchema = new mongoose.Schema({
  author:{
    type: String
  },
  team: [ teamSchema ]
});


module.exports = mongoose.model('Prediction', predictionSchema);

This is my Controller

const mongoose = require('mongoose');
const Prediction = mongoose.model('Prediction');

exports.homePage = (req, res) => {
  res.render('layout', {title: 'Home'});
};

exports.addPrediction = (req, res) => {
  res.render('editPrediction', {title: 'Add Prediction'});
};

exports.createPrediction = async(req, res) => {
  const prediction = new Prediction({
    author: req.body.author,
    team: {
      team1: req.body.team1,
      team2: req.body.team2,
      prediction: req.body.prediction
    }
  });
await prediction.save();
res.redirect('/');
};

And my Form.pug

form.ui.form.segment#register-form(action='/add' method='POST')
    .field
      label Name
      |     
      .ui.left.labeled.icon.input
        input(type='text', placeholder='Name', name='author')
        |        
        i.user.icon  
    #fields
      - for(var i = 0; i < 2; i++)
        .field
          label Team 1
          |     
          .ui.left.labeled.icon.input
            input(type='text', placeholder='Team 1', name='team1')
            |       
            i.soccer.icon
        .field
          label Team 2
          |     
          .ui.left.labeled.icon.input
            input(type='text', placeholder='Team 2', name='team2')
            |       
            i.soccer.icon
        .field
          label Prediction
          |     
          .ui.left.labeled.icon.input
            input(type='text', placeholder='Prediction', name='prediction')
            |       
            i.lock.icon        
    button.ui.button.fluid(type='submit') Save

When I try saving one instance of the prediction, the data saved in the model is as shown in the screenshot.

Database One Instance

When I try saving two instances of the prediction from the form. The second instance of the team is just appended into the first one and not created as a new object that is pushed into the team Array.

Database Multiple Instances

I need a new document to be created and pushed into the team array when I want to save multiple instances of the team from my form. What have I missed?

Upvotes: 1

Views: 600

Answers (2)

kosar
kosar

Reputation: 11

You must define the first schema options as an array:

const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const slug = require('slugs');

const teamSchema = new mongoose.Schema({
team1: [{
type: String
}],
team2: [{
type: String
}],
prediction:[{
type: String
}]
});

const predictionSchema = new mongoose.Schema({
author:{
type: String
},
team: type: teamSchema 
});

and your form.Pug is correct Then you can access them in this way after save:

team.team1[0] team.team2[0] team.prediction[0]

Upvotes: 1

Syed Ayesha Bebe
Syed Ayesha Bebe

Reputation: 1448

Your schema is correct.My suggesstion is use var keyword instead of const because variable is a data structure that contains information that is expected to change. A constant is a data structure that contains information that will never change. If there is room for error, var should always be used. However, not all information that never changes in the lifetime of a program needs to be declared with const. If under different circumstances the information should change, use var to indicate that, even if the actual change doesn't appear in your code.Try this and see if this works.

Upvotes: 0

Related Questions