Closed jingrid closed 7 years ago
Can you post what you have so far? Are you getting errors?
We took the Blog controller and just changed it to make it work for Posts
'use strict'
const controller = require('lib/wiring/controller')
const models = require('app/models')
const Blog = models.blog
const authenticate = require('./concerns/authenticate')
const setUser = require('./concerns/set-current-user')
const setModel = require('./concerns/set-mongoose-model')
const index = (req, res, next) => {
Blog.post.find()
.then(posts => res.json({
posts: posts.map((e) =>
e.toJSON({ virtuals: true, user: req.user }))
}))
.catch(next)
}
const show = (req, res) => {
res.json({
blog: req.blog.toJSON({ virtuals: true, user: req.user })
})
}
const create = (req, res, next) => {
const post = Object.assign(req.body.blog.post, {
_owner: req.blog._id
})
Blog.post.create(post)
.then(post =>
res.status(201)
.json({
post: post.toJSON({ virtuals: true, blog: req.blog })
}))
.catch(next)
}
const update = (req, res, next) => {
delete req.body._owner // disallow owner reassignment.
req.blog.update(req.body.blog)
.then(() => res.sendStatus(204))
.catch(next)
}
const destroy = (req, res, next) => {
req.blog.remove()
.then(() => res.sendStatus(204))
.catch(next)
}
module.exports = controller({
index,
show,
create,
update,
destroy
}, { before: [
{ method: setUser, only: ['index', 'show'] },
{ method: authenticate, except: ['index', 'show'] },
{ method: setModel(Blog), only: ['show'] },
{ method: setModel(Blog, { forUser: true }), only: ['update', 'destroy'] }
] })
However, when we try to create a Post, we are getting a 500 error: "{"error":{"message":"Cannot read property 'post' of undefined","error":{}}}"
Our curl request is as follows:
API="http://localhost:4741" URL_PATH="/blogs"
curl "${API}${URL_PATH}/${ID}/posts" \ --include \ --request POST \ --header "Content-Type: application/json" \ --header "Authorization: Token token=${TOKEN}" \ --data '{ "post": { "title": "'"${TITLE}"'", "body": "'"${BODY}"'" } }'
echo
Our custom route is: .post('/blogs/:id/posts', 'posts#create')
Cannot read property 'post' of undefined
suggests that you have some code like thing.post
, where thing
is undefined. You should be able to confirm that's what's happening with some console.log
s.
Refactored your code a lil bit by adding "``js" and "
bash" around your curl script.
We took the Blog controller and just changed it to make it work for Posts
'use strict'
const controller = require('lib/wiring/controller')
const models = require('app/models')
const Blog = models.blog
const authenticate = require('./concerns/authenticate')
const setUser = require('./concerns/set-current-user')
const setModel = require('./concerns/set-mongoose-model')
const index = (req, res, next) => {
Blog.post.find()
.then(posts => res.json({
posts: posts.map((e) =>
e.toJSON({ virtuals: true, user: req.user }))
}))
.catch(next)
}
const show = (req, res) => {
res.json({
blog: req.blog.toJSON({ virtuals: true, user: req.user })
})
}
const create = (req, res, next) => {
const post = Object.assign(req.body.blog.post, {
_owner: req.blog._id
})
Blog.post.create(post)
.then(post =>
res.status(201)
.json({
post: post.toJSON({ virtuals: true, blog: req.blog })
}))
.catch(next)
}
const update = (req, res, next) => {
delete req.body._owner // disallow owner reassignment.
req.blog.update(req.body.blog)
.then(() => res.sendStatus(204))
.catch(next)
}
const destroy = (req, res, next) => {
req.blog.remove()
.then(() => res.sendStatus(204))
.catch(next)
}
module.exports = controller({
index,
show,
create,
update,
destroy
}, { before: [
{ method: setUser, only: ['index', 'show'] },
{ method: authenticate, except: ['index', 'show'] },
{ method: setModel(Blog), only: ['show'] },
{ method: setModel(Blog, { forUser: true }), only: ['update', 'destroy'] }
] })
However, when we try to create a Post, we are getting a 500 error: "{"error":{"message":"Cannot read property 'post' of undefined","error":{}}}"
Our curl request is as follows:
#!/bin/bash
API="http://localhost:4741"
URL_PATH="/blogs"
curl "${API}${URL_PATH}/${ID}/posts" \
--include \
--request POST \
--header "Content-Type: application/json" \
--header "Authorization: Token token=${TOKEN}" \
--data '{
"post": {
"title": "'"${TITLE}"'",
"body": "'"${BODY}"'"
}
}'
echo
Our custom route is:
.post('/blogs/:id/posts', 'posts#create')
See @cpearce31 's suggestion.
perhaps this line?
Blog.post.create(post)
can you see what Blog
is at that point in your create action?
I have figured out how to target the posts array in the blog object and I can access the data I want to push into it but my promise chain seems to be not returning data to be passed on and I cannot figure out why
const create = (req, res, next) => {
// const post = Object.assign(req.body.post, {
// _owner: req.user._id
// })
console.log('this is req.params: ', req.params)
console.log('this is Blog', Blog)
return Blog.find(req.params.id)
.then(blog => console.log('this is req.body.posts ', req.body))
.then(blog => console.log('this is blog.posts ', blog[0].posts))
.then(blog => blog[0].posts.push(req.body.posts)
.then((blog) => blog.save())
.then(() => res.sendStatus(204))
.json({
post: blog.toJSON({ virtuals: true, blog: req.blog })
}))
.catch(next)
}
This is the error I am receiving ~/wdi/projects/Project-3-backend (blog) $ TOKEN=IJ27sSn03JI2OG2l2EBmMM/WK1ruhBuIBRonoh8poNo=--VTtumr8xDzNgrN/Ln91X98L3xysay5RWeij1bcxfSso= ID=5989bdac1e09c5de6ff8a525 TITLE=BLOG1 BODY=DSKJFLFJDSLKFJDLSKFJDLKJS sh scripts/posts/create-post.sh HTTP/1.1 500 Internal Server Error X-Powered-By: Express Access-Control-Allow-Origin: http://localhost:7165 Vary: Origin Content-Type: application/json; charset=utf-8 Content-Length: 72 ETag: W/"48-5HVhgdyPUn6SQhuWh0tFROztoWY" Date: Tue, 08 Aug 2017 14:44:13 GMT Connection: keep-alive
{"error":{"message":"Cannot read property '0' of undefined","error":{}}} ~/wdi/projects/Project-3-backend (blog) $
so likely somewhere in there that you have blog[0] it isn't what you think it is? have you logged the data getting passed into each .then?
the chain stops after the first .then regardless of what I pass in as the first callback. If I console.log it as the first .then() it is what I am looking for
This is what I am console.logging and then what is being pushed
.then(blog => console.log('this is blog.posts ', blog[0].posts))
.then(blog => console.log('this is req.body.posts ', req.body.posts))
.then(blog => blog[0].posts.push(req.body.posts)
This is what the terminal feeds back
(node:57545) DeprecationWarning: open()
is deprecated in mongoose >= 4.11.0, use openUri()
instead, or set the useMongoClient
option if using connect()
or createConnection()
. See http://mongoosejs.com/docs/connections.html#use-mongo-client
Server listening on port 4741
this is req.params: { id: '5989bdac1e09c5de6ff8a525' }
this is Blog function model(doc, fields, skipId) {
if (!(this instanceof model)) {
return new model(doc, fields, skipId);
}
Model.call(this, doc, fields, skipId);
}
this is blog.posts []
this is req.body.posts { title: 'BLOG1', body: 'DSKJFLFJDSLKFJDLSKFJDLKJS' }
POST /blogs/5989bdac1e09c5de6ff8a525/posts 500 44.480 ms - 72
Correction it makes it past both console.logs
but as you can see I am targeting the array and the object that I want to be pushed to the array
bump
it says req.body.posts is an object no? you can use .push on an object?
Im pushing the object to the array Im calling .push on the array shouldn't that work?
I think It might be a promise problem but I do not know what to do about it
so is the problem that the object isn't getting pushed into the array?
Update
Console.logs where returning undefined and there was a syntax error that resulted in one big nested promise chain
Were you able to sort out the nested promises once you discovered the syntax error?
Hello
We're trying to create the controller for our nested schema, but we're having trouble referencing the right things.
Essentially, we have a schema/model for Blog, and we are trying to make Posts nested within Blog.