Reputation: 1834
Having trouble saving an embedded array to a Mongoose model.
Please see Edit at bottom.
I have a form to create BlogPost in Express using Mongoose to store data in mongo. I can create and view new blogposts however I just added an embedded document schema Feed into the BlogPost model and I can't get Feed arrays to save from the form into the model
code:
BlogPosts.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_database');
var Schema = mongoose.Schema
, ObjectId = Schema.ObjectId;
var Feeds = new Schema({
name : { type: String }
, key : { type: String }
});
var BlogPost = new Schema({
author : ObjectId
, title : { type: String, required: true, index: { unique: true } }
, date : { type: Date, required: true, default: Date.now }
, feeds : [Feeds]
});
mongoose.model('BlogPost', BlogPost);
web.js
...
app.get('/blogpost/new', function(req, res) {
res.render('blogposts/blogpost_new.jade', { locals: {
title: 'New BlogPost'
}
});
});
app.post('/blogpost/new', function(req, res){
var b = new BlogPost(req.body.b)
b.save(function() {
b.feeds.push();
res.redirect('/blogposts');
});
});
...
var BlogPost = mongoose.model('BlogPost', BlogPost);
Jade form
form( method="post")
div
div
span Title :
input(type="text", name="b[title]", id="editBlogPostTitle")
div
span Feeds :
ul
li
span name
textarea( name="f[name]", rows=20, id="editBlogPostBodyName")
li
span key
textarea( name="f[key]", rows=20, id="editBlogPostBodyKey")
div#editBlogPostSubmit
input(type="submit", value="Send")
If I fill out this form, the model posts and saves but the feeds data isn't there ("feeds" : [ ]
).
How should I properly submit the feeds data to save to the array?
Edit
So I have managed to set up a form to save a Feed object with name
and key
within a BlogPost doing the following. However, this still needs to be improved to allow for multiple Feeds to be saved at the time of creating a single BlogPost. With my current solution I can only save one Feed properly. Thoughts?
blogposts.js (just change Feeds to Feed
var Feed = new Schema({
...
web.js (just moved the push)
app.post('/blogpost/new', function(req, res){
var b = new BlogPost(req.body.b)
b.feeds.push(req.body.feed);
b.save(function() {
res.redirect('/blogposts');
});
});
form (just change feed names)
li
span name
textarea( name="feed[name]", rows=20, id="editBlogPostBodyKey")
li
span key
textarea( name="feed[key]", rows=20, id="editBlogPostBodyKey")
This saves properly, I just can't create multiple feeds within a blogpost at the time of saving. Any help greatly appreciated. thanks.
Upvotes: 1
Views: 6734
Reputation: 1834
For what it's worth, I did get this to work. See my edit above which worked once I added an [] to the feed name: "feed[0][name]" and "feed[0][key]"
, and then "feed[1][name]" and "feed[1][key]"
. Thanks Chance for some good ideas. For me it didn't work to put that logic in the 'get' route, it needed to be in the 'post'. Thanks a lot tho.
Upvotes: 0
Reputation: 11285
For the routes:
You do not need to do b.feeds.push();
on the post side. I have a push on the get side when creating a new object, but only because I expect there to be at least 1 nested model. Then again, seeing as how you have a list you may want to add the b.feeds.push();
on the get side as well.
For the view, you need to keep the model intact.
Assuming b is blogpost and it is your parent to the f list, then you'd want:
span Feeds :
- var i = 0;
ul
- each feed in blogPost.feeds
li
span name
textarea( name="blogPost[feeds][i][name]", rows=20, id="editBlogPostBodyName")=feed.name
li
span key
textarea( name="blogPost[feeds][i][key]", rows=20, id="editBlogPostBodyKey")=feed.key
- i++
routes.js (or routes/blogPosts.js):
app.get('/blogpost/new', function(req, res) {
post = new BlogPost();
post.feeds.push(new Feed());
res.render('blogposts/blogpost_new.jade', { locals: {
title: 'New BlogPost',
blogPost: post
}
});
});
edit i changed b to blogPost and f to feed in the view. also added the "new" logic in the routes definition.
On a side note, keep in mind that any routes will not be editable in this case. It should, in theory, drop and save any new feeds in the even of editing them (if you were to have an update action). If you want them to be independent entities that can be edited, then you need to provide them ids and have add a means of getting them by id. That approach is outlined on mongoosejs.com i believe.
Upvotes: 1