Naor Malca
Naor Malca

Reputation: 143

build schema correct in mongoDB/mongoose

I'm trying to make a poll vote app. My big problem is that I can't make an array of objects and access them. I try to make a few option votes to one poll like that:

title:"question?"
option:content:"1 answer",vote:0
       content:"2 answer",vote:0 
       content:"3 answer",vote:...

and build schema like that:

var mongoose = require("mongoose");
var pollSchema = new mongoose.Schema({
   title: String,
   maker :{
      id:{
         type: mongoose.Schema.Types.ObjectId,
         ref: "User"
      },
      username: String
   },
   options:[{content: String,vote:{type:Number,default:0}}]
});
module.exports = mongoose.model("Poll",pollSchema);

and get the data from there:

<div class="form-group" id="option">
  <label for="Option 1">Options</label>
  <input type="text" class="form-control" name="options[content]" placeholder="Option 1">
  <input type="text" class="form-control" name="options[content]" placeholder="Option 2">
</div>

and the output in mongoDB is:

{
 "_id": {
     "$oid": "5993030dc5fa8c1b4f7eb176"
 },
 "title": "Some question?",
 "options": [
     {
         "content": "opt 1,opt 2",
         "_id": {
             "$oid": "5993030dc5fa8c1b4f7eb177"
         },
         "vote": 0
     }
 ],
 "maker": {
     "username": "Naor Malca"
 },
 "__v": 0
}

I want each option to have separate content, id and vote. maybe i input the data worng?or the schema is worng?

UPDATE: This my route code:

    //NEW POLL ROUTE
app.post("/",function(req, res){
    var title   = req.body.title;
    var options = req.body.options;
    var maker   = req.body.maker;
    var newPoll = {title:title,options:options,maker:maker};
    Poll.create(newPoll,function(err,poll){
        if(err){
            res.send("create error");
        } else{
            res.redirect("/");
        }
    });
});

still not working this the output:(its make the text an array not a array of objects...)

{ _id: 5993fcad9a63350df274b3e5,
  title: '111',
  __v: 0,
  options: [ { text: '222,333', _id: 5993fcad9a63350df274b3e6, vote: '0' } ],
  maker: { username: 'naor' } }

Upvotes: 0

Views: 342

Answers (1)

Mikey
Mikey

Reputation: 6766

When you build your form, add [number] so that each option is different.

<div class="form-group" id="option">
    <label for="Option 1">Options</label>
    <input type="text" class="form-control" name="options[0][content]" placeholder="Option 1" value="value1">
    <input type="text" class="form-control" name="options[1][content]" placeholder="Option 2" value="value2">
</div>

That way when you submit the form, it should come back as array of objects

req.body.options = [
    { content: 'value1' },
    { content: 'value2' }
]

This is a typical approach when you build an "add" form containing grouped elements.

--

When it comes to an "edit" form such that you want to update existing options, you can pass the option's _id

Here's an example using EJS

<div class="form-group" id="option">
    <label for="Option 1">Options</label>
    <% poll.options.forEach(option => { %>
        <input type="text" class="form-control" name="options[<%= option._id %>][content]" placeholder="Option 1" value="<%= option.content %>">
    <% }) %>
</div>

Here req.body.options should be an object

req.body.options = {
    'some-id': { 
        content: 'value1' 
    },
    'another-id': { 
        content: 'value2' 
    }
}

When you save, you would iterate over the object with the key i.e. _id. I think you can make use of id() to find the object to set.

--

If it doesn't come back in the formats mentioned above, you most likely need to use and set the bodyParser.

Upvotes: 1

Related Questions