How do nested pages/mongoose schemas work? Getting errors - javascript

I am making a site that is a mock forum where the user clicks on a forum topic, goes to a unique .ejs page with forums, and then goes to another unique .ejs page where the forum is, where both pages are altered based on what the user fills into a Form on the previous page. The first step worked, but I keep getting either a TypeError "can't read property name of null" or a reference error (depending on what object info I type into the .ejs page) when I end up clicking on a link that would go from the "forum topic" page to the "forum". Data is being added to the database and I created corresponding mongoose schemas that are linked to each other and the main app so I'm not sure what the issue is.
I'm using this with express and mongodb/mongoose, the page that's getting the type error is a .ejs page. I'm assuming the main issue is in one of the routing blocks in the main app document, but it may not be and it may be some other concept or page configuration I'm not getting. What is the deal with nested schemas and pages for those who are more experienced with this?
Here is the page itself that has the error:
TypeError: /Users/roberts4/project_4/views/forum.ejs:4
2|
3| <nav class = "container">
>> 4| Welcome to Forum/ <%= forum.name %>
5| Reply
6| <a class = "btn btn-primary btn-sm" href="/main/<%= forumtopic._id
%>/<%= forum._id %>/reply/new">Add New Forum</a>
7|
Cannot read property 'name' of null
The post function that you will see has has the "forum" created inside of the "forumtopic" id, unlike for what I did when posting the "forumtopic" itself.I tried adding req.body variables but it seems like that's only used if you're not posting them to a different page.
///there is code above this for forumtopic that's similar, except the
////.post block has the .create by itself and not inside of .findById
app.get("/main/:id/forum", function(req, res){
Forum.find({}, function(err, allForums){
if(err){
console.log(err);
} else {
res.render("forumtopic", {forums: allForums});
}
})
});
app.post("/main/:id/forum", function(req, res){
ForumTopic.findById(req.params.id, function(err, forumtopic){
if(err){
console.log(err);
res.redirect("/main");
} else {
//console.log(req,body.comment);
Forum.create(req.body.forum, function(err, forum){
if(err){
console.log(err);
} else {
forumtopic.forums.push(forum);
forumtopic.save();
res.redirect('/main/' +
forumtopic._id);
}
})
}
})
});
app.get("/main/:id/forum/new", function(req, res){
ForumTopic.findById(req.params.id, function(err, forumtopic){
if(err){
console.log(err);
} else {
res.render("newforum", {forumtopic: forumtopic});
}
})
});
app.get("/main/:id/:forumid", function(req, res) {
Forum.findById(req.params.id).populate("replies").exec(function(err,
foundForum) {
if(err){
console.log(err);
} else {
console.log(foundForum);
res.render("forum", {forum: foundForum});
}
})
});
///there is code below this that's not accessed yet because of the error
Getting a TypeError 'cannot read property name of null', expecting
a page that displays information based off of node in the app.js.

Related

How to pass Mongoose return variable in NodeJS Express router res.render?

I had set a basic Express NodeJS server.
I want to save the value of the setting returned from mongoose.find() to res.render as a variable, but every time it's throwing me an error that Cannot read property of undefined.
Here is my routes.js file.
var Setting = require('../../models/setting');
module.exports = function(app, passport) {
app.get('/admin', function(req, res) {
Setting.find(function(err, setting) {
if (err) {
return res.send(500, err);
}
console.log(setting);
res.render('admin/customize/settings', {
title: 'Change Setting | eduBird',
user: req.user,
setting: res.setting
// setting: res.settings
});
});
});
This is my setting model:
var mongoose = require('mongoose');
var settingSchemma = mongoose.Schema({
logo: {
logo16: String,
logo32: String,
logo96: String,
logo128: String,
logo128white: String
}
});
module.exports = mongoose.model('Setting', settingSchemma);
Here is the error in the browser, I am using pug view.
name='logo32' value=setting.logo.logo32) Cannot read property 'logo' of undefined
Here is my the log in my terminal, notice that console.log(setting) is executing the settings right, since I have just one document for logo.
[nodemon] starting `node ./bin/www server`
Server running on port3000
[ { _id: 58ac45xxxx3xxxxf3,
__v: 0,
logo:
{ logo128white: 'https://res.cloudinary.com/xxxxx/image/uplo
ad/xxxxx/128x128-white_aqya8e.png',
logo128: 'https://res.cloudinary.com/xxxxx/image/upload/v1
xxxxxxx/128x128_jn9dzz.png',
logo96: '',
logo32: 'https://res.cloudinary.com/xxxx/image/upload/v14
xxxxx/32x32_wtk3gk.png',
logo16: 'https://res.cloudinary.com/pinterested222/image/upload/v14
xxxx/16x16_o4gzhd.png' } } ]
GET /stylesheets/style.css 304 6.947 ms - -
Here is a snapshot:
Snapshot of the error
UPDATE
Here is the snippet of my .pug file, I am rendering, all indentations are right.
form.logoForm.z-depth-3.col.s12(method='post' action='/settings/logo')
.row
.col.s12.m8.offset-m2
h4.center Change Logo Settings
p.center Add URL for valid Logos.
.divider
.input-field.col.s12
input.validate#logo16(placeholder="URL for 16x16 .png log" name='logo16' value=setting.logo.logo16)
label.active(for='logo16') 16x16 Logo
.input-field.col.s12
input.validate#logo32(placeholder="URL for 32x32 .png log" name='logo32' value=setting.logo.logo32)
label.active(for='logo32') 32x32 Logo
.input-field.col.s12
input.validate#logo128(placeholder="URL for 128x128 .png log" name='logo128' value=setting.logo.logo128)
label.active(for='logo128') 128x128 Logo
.input-field.col.s12
input.validate#logo128white(placeholder="URL for 128x128 white .png log" name='logo128white' value=setting.logo.logo128)
label.active(for='logo128white') 128x128 Logo White(for dark bg)
.row
.col.s12.m4.offset-m4.l4.offset-l4
button.center.logoSubmit.btn.btn-large.indigo.darken-4.white-text.waves-effect.waves-light.disabled Save #[i.fa.fa-chevron-circle-right.right]
button.center.btn.btn-large.indigo.darken-4.white-text.waves-effect.waves-light Save #[i.fa.fa-chevron-circle-right.right]
.col.s12.m6.offset-m3
p.center(style='margin-top: .3em; padding: .2em') *You can only save the settings if any of the form fields are different/updated.
You have a typo in your code, the assignment setting: res.setting is the one causing the issue. Also, find() returns an array of docs, not a single document. You may want to use findOne() for that:
var Setting = require('../../models/setting');
module.exports = function(app, passport) {
app.get('/admin', function(req, res) {
Setting.findOne({}).exec(function(err, setting) {
if (err) {
return res.send(500, err);
}
console.log(setting);
res.render('admin/customize/settings', {
title: 'Change Setting | eduBird',
user: req.user,
setting: setting
});
});
});
}

Sails.js error issue while deleting any record

I am new in sails js , Here i am follow one tutorial to create crud using sails js and mongodb.
But while deleting any record getting 500 internal server error
console error
"NetworkError: 500 Internal Server Error - http://localhost:1337/user/delete/55bf315ee3437a512628916b"
Here is my controller file delete function:
delete: function(req, res) {
var id=req.param("id",null);
User.findOne(id).done(function(err, user) {
// we now have a model with instance methods attached
// destroy the record
user.destroy(function(err) {
res.redirect( 'user/index/');
// record has been removed
});
});
}
Here is my view
+Create
<ol>
<% users.forEach( function( model ){ %>
<li><%= model.name %>(delete||Update||view)</li>
<% }); %>
</ol>
// Here is my route file
module.exports.routes = {
'/': {
view: 'homepage'
},
'post/User':{
view: 'user/create'
}
};
Please guide me i dont't know where i am doing mistake.
Thanks in advance
I think the mistake could be in the res.redirect,
you should place it outside destroy() function.
delete: function(req, res) {
var id=req.param("id",null);
User.findOne(id).done(function(err, user) {
// we now have a model with instance methods attached
// destroy the record
user.destroy(function(err) {
if (err) return
});
res.redirect( 'user/index/');
});
}
I was fixed the error , its come since i am using
User.findOne(id).done(function(err, user) {
..
}
Insted of this :
User.findOne(id).exec(function(err, user) {
.. ^^^^^^
}

MeanJS stack, debugging Angular error: fnPtr is not a function

I'm learning the MeanJS stack (Mongo, Express, Angular, Node) and writing a simple todo webapp. I can list all todos and create a new one. When I 'edit' a todo, I'm encountering this error:
TypeError: fnPtr is not a function
I'm assuming I have some naming or syntax wrong (based on this and this SO question)
The problem is I don't know where to look for wrong naming or bad syntax since the file structure is pretty large ('app' and 'public' maps are 484 files). I don't get into the todo.client.controller nor 'todo.server.controller' update function, as there is a console log there that doesn't get printed. The edit button is a submit input, but I don't know where it goes next.
Code:
Piece form 'edit' page
<div class="form-group">
<input type="submit" value="Update" class="btn btn-default">
</div>
Client controller:
// Update existing Todo
$scope.update = function() {
console.log('update');
var todo = $scope.todo;
todo.$update(function() {
$location.path('todos/' + todo._id);
}, function(errorResponse) {
$scope.error = errorResponse.data.message;
});
};
Server controller:
/**Update a Todo*/
exports.update = function(req, res) {
console.log('todo controller');
var todo = req.todo;
todo = _.extend(todo, req.body);
Todo.update({_id: req.body._id}, req.body, function(err, update) {
//todo.save(function(err) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.json(todo);
}
});
};
Anyone experienced with the MeanJS stack or Angular that could point me in a direction to start debugging?
You have not added ng-click to the "Update" submit button.
Change your code to this:
<div class="form-group">
<input type="submit" value="Update" ng-click="update()" class="btn btn-default">
</div>
As for the fnPtr error, add your full stack trace so that it can be analyzed.
Also check if your code has closed all the brackets, you are not using same name for 2 variables and typos.

Mongoose $push from HTML Form not working

Can anyone tell me what am I doing wrong.
My HTML Form:
<form action="/user/:id" method="put">
<div class="form-group">
<label>Miles</label>
<input type="text" class="form-control" name="miles">
</div>
<button type="submit" class="btn btn-warning btn-lg">Login</button>
</form>
My Express Route:
app.put('/user/:id', function(req, res) {
User.findById(req.body.params.id, function(err, user) {
if (err)
res.send(err);
console.log(user.id);
User.findByIdAndUpdate(
user.id,
{$push: {"milesLog": {miles: req.body.miles}}},
{safe: true, upsert: true},
function(err, model) {
console.log(err);
},
res.json(user)
);
Posting from my HTML form I get the following Error:
Cannot GET /user?miles=66&activity=asdasd
But When I test this through POSTMAN it works:
What am I doing wrong. Why doesn't it work from my HTML Form?
The route doesn't match, you have this URL
/user?miles=66&activity=asdasd
and then this route
app.put('/user/:id', ....
that route is looking for something like this
/user/66
it doesn't look for querystrings, that would be
app.put('/user', function(req, res) {
var miles = req.query.miles;
var activity = req.query.activity;
and unless you have a really good reason for using PUT request, you should change that to use GET instead.
Also, <form action="/user/:id" ... isn't a valid URL, you can't have colons in the URL, and you seem to have misunderstood a little, the :id in your route matches anything, as long as it's a valid route, so it will match
/user/frank
/user/77
/user/something?querystring
etc. and then you can access that inside the route
app.get('/user/:id', function(req, res) {
var user = req.params.id; // returns "frank" etc
There is no "PUT" verb in html forms, while you are implementing it like this:
<form action="/user/:id" method="put">
You have to use method="POST" in html form and change your route to:
app.post('/user/:id')
It's not a bad thing to use such method.
However if you are developing a front-end application it's common to use XMLHttpRequest object which has "PUT" verb, and your route will work just fine.

Sails.js - How to render a partial from a controller?

I have a partial view containing my login form. I would like to render it from an ajax call to my controller.
This is the sample where i would return my partial view:
postlogin: function (req,res) {
var username = req.param('username');
var password = req.param('password');
User.find({
username: username,
password: password.salt()
}).done(function(err, users){
if(users.length == 1){
// Here I want to return a partial view, not a view
res.view('home/login', {message: 'Login success!'});
}else{
// Here I want to return a partial view, not a view
res.view('home/login', {message: 'Login failed!'});
}
});
},
Ah! Found it!
If your view is a partial view, simply specify layout: null:
res.view('home/login', {message: 'Login failed!', layout: null});
Bottom of the page: http://sailsjs.org/#!documentation/views
What about using multiple layouts?
Express 3 removed native support for layouts. In Sails, we've managed to keep this around, but we don't officially support multiple layouts.
That said, at least in EJS, instead of indicating your custom layout with the layout local, you must use _layoutFile:
/**
* HomeController
*/
module.exports = {
index: function (req, res) {
res.view({
_layoutFile: '../layouts/other.ejs'
});
},
};
Sails v0.9.7

Categories

Resources