Sails.js: Sending 500 ("Server Error") and User not defined at eval - sails.js

I'm trying to create a view show in Sails. This is my code:
api / models / User.js:
module.exports = {
attributes: {
name: {
type: 'string',
required: true
},
lastname: {
type: 'string',
required: true
},
username: {
type: 'string',
required: true,
unique: true
}
}
};
api / controllers / UserController
Controller
module.exports = {
new:function (req, res) {
console.log('entre al formulario');
res.view();
},
create:function(req, res){
var userObj={
name : req.param('name'),
lastname : req.param('lastname'),
username : req.param('username')
}
User.create(userObj, function(err, user){
if(err){
console.log("Se encontro un error");
return res.redirect('/');
}
res.redirect('/user');
console.log("correcto");
});
},
show: function(req, res, next){
User.findOne(req.param('id'), function userFounded(err, user){
if(err)
console.log(err);
return next(err);
res.view({
user: user
});
});
}
};
And this is my view:
Show.ejs
When I go to localhost:1337/user/show/ this error comes out:
Error showing in console
However, I can insert, but I can't view the elements in the view show.ejs. Does someone know how to solve this?
Thank you in advance for help.

If you created your page with sails generate page *name* then you should have a name.page.js . There you have an data() {} section. In this section you have to define your user like user: {}

Related

How to access model attributes of different controller in Sails.js?

I have two controllers/models in my Sails project which is Clubs and Members. One club can have many members.
I try to put the id of 'Clubs' as a reference id (like a foreign key) in 'Members', so that I can retrieve the members of a club by using the reference id in 'Members'. I want to display the members according to their clubs at the homepage. However I could not find a way to pass the id value of 'Clubs' to the 'Members' controller. Below are some of the codes:
Clubs.js
module.exports = {
attributes: {
clubName: {
type: 'string',
},
clubDesc: {
type: 'string',
},
},
};
Members.js
module.exports = {
attributes: {
memberName: {
type: 'string',
},
clubId: {
type: 'string',
},
},
};
ClubsController.js
module.exports = {
list: function(req, res) {
Clubs.find({}).exec(function(err, club) {
if(err) {
res.send(500, {error: 'Database Error'});
}
res.view('pages/club-list', {clubs:club});
});
},
add: function(req, res) {
res.view('pages/club-add');
},
create: function(req, res) {
var clubName = req.body.clubName;
var clubDesc = req.body.clubDesc;
Clubs.create({clubName:clubName, clubDesc:clubDesc}).exec(function(err){
if(err) {
res.send(500, {error: 'Database Error'});
}
res.redirect('/clubs/list');
});
},
};
MembersController.js
module.exports = {
list: function(req, res) {
Members.find({}).exec(function(err, member) {
if(err) {
res.send(500, {error: 'Database Error'});
}
res.view('pages/member-list', {members:member});
});
},
add: function(req, res) {
res.view('pages/member-add');
},
create: function(req, res) {
var memberName = req.body.memberName;
var clubId = req.body.clubId;
Members.create({memberName:memberName,
clubId:clubId}).exec(function(err){
if(err) {
res.send(500, {error: 'Database Error'});
}
res.redirect('/members/list');
});
},
};
routes.js
module.exports.routes = {
'/': {
view: 'pages/homepage',
},
'/clubs/list': {
view: 'pages/club-list',
controller: 'Clubs',
action: 'list'
},
'/clubs/add': {
view: 'pages/club-add',
controller: 'Clubs',
action: 'add'
},
'/clubs/create': {
controller: 'Clubs',
action: 'create',
},
'/members/list': {
view: 'pages/member-list',
controller: 'Members',
action: 'list'
},
'/members/add': {
view: 'pages/member-add',
controller: 'Members',
action: 'add'
},
'/members/create': {
controller: 'Members',
action: 'create',
},
};
I'm really new to Sails.js here and I find that it's quite difficult to get resources on this matter. I'm not sure if I put this in a way that you guys could understand. But do ask for more details if you guys need more understanding. Thank you in advance.
If I understand correctly, you're looking to create a one-to-many association between Clubs and Members. Here's how it should look in Clubs.js, your 'many':
attributes: {
...
members: {
collection: 'Members',
via: 'club'
}
}
Then in Members.js, your 'many':
attributes: {
...
club: {
model: 'Clubs'
}
}
When you do Club.find(), the members key will be an array of member ids. If you do Club.find().populate('member'), the members key will be an array of fully-populated member objects.
Here are the docs on associations.
This isn't directly related to your question, buy since you are new to Sails, I am including a comment that will give you some advice on how to best use the framework. I hope it goes well!

Q: How can I evade storing duplicated users with Sails?

I have coded a very simple sails app that just has passport authentication implemented. I use mongoDB as local database and I can't get to deny the creation of users with duplicated email. (I already have unique: true in the email attribute). Any idea what could I be missing?
var bcrypt = require('bcrypt');
module.exports = {
attributes: {
email: {
type: 'email',
required: true,
unique: true
},
password: {
type: 'string',
minLength: 6,
required: true
},
toJSON: function() {
var obj = this.toObject();
delete obj.password;
return obj;
}
},
beforeCreate: function(user, cb) {
bcrypt.genSalt(10, function(err, salt) {
bcrypt.hash(user.password, salt, function(err, hash) {
if (err) {
console.log(err);
cb(err);
} else {
user.password = hash;
cb();
}
});
});
}
};
Here I create users:
signup: function (req, res) {
User.create(req.params.all()).exec(function (err, user) {
if (err) return res.negotiate(err);
req.login(user, function (err){
if (err) return res.negotiate(err);
return res.redirect('/welcome');
});
});
}
The proper way to get errors when adding users is to check the Error object returned by the User.create() method (Promise or exec() method).
Example with Bluebird Promise :
User.create({ email : 'foo#bar.com', password : 'secret' })
.then((newUser) => {
/* do something with newly created user `newUser` */
/* eg : return res.view('user/added.ejs', newUser); */
})
.catch((err) => {
/* do something with the Error object `err` */
/* It should tell you if email already exists */
/* eg : return res.badRequest(err.message); */
});
Example with exec() method :
User.create({ email : 'foo#bar.com', password : 'secret' })
.exec((err, newUser) => {
if (err) {
/* do something with the Error object `err` */
} else {
/* do something with newly created user `newUser` */
}
});

How to make querys when tou have many to many relationships between models?

i am trying to make a game. I need tu create a Match. I think the problem on this Way. The User create a Match. In a third table I save playerId and gameId. When another user join the match, I save again, playerId and gameId. Then, I make a query with player with gameId in common, and start the game.
first, One User may have many Games. second, One Match may have many Games. this is the Match model:
module.exports = {
attributes: {
name: {
type: 'string'
},
description: {
type: 'string'
},
game: {
collection: 'game',
via: 'gameId',
}
}
};
This is the User model:
var bcrypt = require('bcrypt');
module.exports = {
attributes: {
name: {
type:'string'
},
email: {
type: 'email',
required: true,
unique: true
},
password: {
type: 'string',
},
passwordConfirmation: {
type: 'string'
},
passwordEncrypted: {
type: 'string'
},
creator: {
collection: 'game',
via: 'playerId'
},
toJSON: function(){
var obj = this.toObject();
delete obj.password;
delete obj.passwordConfirmation;
delete obj._csrf;
return obj;
}
}, beforeCreate: function(values, next){
console.log("Acabo de entrar a eforeCreate");
var password = values.password;
var passwordConfirmation = values.passwordConfirmation;
if(!password || !passwordConfirmation || password != values.passwordConfirmation) {
var passwordDoesNotMatchError = [{
name: 'passwordDoesNotMatchError',
message: 'Las contraseñas deben coincidir'
}]
return next({
err: passwordDoesNotMatchError
});
}
require('bcrypt').hash(values.password, 10, function passwordEncrypted(err, EncryptedPassword){
values.EncryptedPassword = EncryptedPassword;
next();
});
}
};
This is the Game model:
module.exports = {
attributes: {
gameId: {
model: 'match'
},
playerId: {
model: 'user'
}
}
};
finally, this is my controller:
module.exports = {
createMatch: function(req,res){
var matchObj = {
name: req.param('name'),
description: req.param('description'),
}
Match.create(matchObj, function(err, match){
if(err){
console.log("el error fue: " + err);
return res.send(err);
} console.log("Entro en create");
return res.json(match);
})
var gameObj = {
gameId: 'aclaration: I dont know how do I get the match.id',
playerId: req.session.me
}
Game.create(gameObj,function(err,game){
console.log("entro a GameCreate");
if(err){
return res.send(err);
} return res.json(game);
})
}
};
I can create the Match, but Game.create send this error:
_http_outgoing.js:344 throw new Error('Can\'t set headers after they are sent.'); ^
Error: Can't set headers after they are sent.
Somebody can help me? probably, I have many errors. Thanks.
Couple of things here:
Having an explicit Game model is not required in Sails. It can manage it implicitly, unless you want to store more information than just gameId and userId. So, you can just do away with Game model.
Please refer for async programming: How do I return the response from an asynchronous call?
Below code should work for you. Hope it helps.
module.exports = {
createMatch: function(req, res) {
var matchObj = {
name: req.param('name'),
description: req.param('description'),
};
Match.create(matchObj, function(err, match) {
if (err) {
console.log("el error fue: " + err);
return res.send(err);
}
console.log("Entro en create");
var gameObj = {
gameId: match.id,
playerId: req.session.me
};
Game.create(gameObj, function(err, game) {
console.log("entro a GameCreate");
if (err) {
return res.send(err);
}
return res.json(game);
// return res.json(match);
});
});
}
};

Sails.js: cannot do POST for inserting into mongoDB

I am trying to write a toy program for submitting form and inserting into mongodb, but I keep getting DB error. Let me paste the relevant code here, and I hope to get some help.
I am using Sails ver 0.10.5 and the latest mongo 2.6.5, and my I run node on my Mac OSX 10.9:
Model: Employee.js
module.exports = {
attributes: {
name: {
type: "string",
required: true
},
email: {
type: "string",
required: true
},
password: {
type: "string",
required: true
}
},
beforeCreate: function(values, next) {
next();
}
};
route.js:
module.exports.routes = {
'/registeremployee': {
controller: 'employee',
action: 'register'
},
'/listemployees': {
controller: 'employee',
action: 'list_all'
}
};
EmployeeController.js
module.exports = {
index: function(req, res) {
res.send(200, {title: "employee index page"});
},
list_all: function(req, res) {
Employee.find().exec(function(err, employee) {
if (err) {
res.send(500, {title: 'error retrieving users'});
} else {
res.send(200, {'employees': employee});
}
});
},
register: function(req, res) {
if (req.method == "GET") {
res.view({title: "Form for registering employees"});
} else if (req.method == "POST") {
var username = req.param("username");
var password = req.param("password");
var email = req.param("email");
console.log("saving the username: " + username); //username printed as 'undefined'
Employee.create({username: username, password: password, email: email}).exec(function(error, employee) {
if (error) {
console.log('error');
res.send(500, {error: "DB error!"});
} else {
console.log('error');
res.send(200, employee);
console.log("saved employee: " + employee.username);
}
});
}
}
};
Lastly, the register.ejs template file:
List All Users
<h2>Form - Create a User</h2>
<form action="/registeremployee" method="POST">
<table>
<tr><td>Name</td><td><input type=”text” name=”username” required></td></tr>
<tr><td>Password</td><td><input type=”password” name=”password” required></td></tr>
<tr><td>Email</td><td><input type=”email” name=”email” required></td></tr>
<tr><td></td><td><input type="submit"></td>
</table>
</form>
It looks to me that the form does not submit data, as the parameters are printed as undefined/null in my controller.
I have this in my connections.js:
mongo: {
adapter: 'sails-mongo',
host: 'localhost',
port: 27017,
user: '',
password: '',
database: 'sailsApp1'
}
just replace name to username and you are able to save data in db.
module.exports = {
attributes: {
username: {
type: "string", required: true },
email: { type: "string", required: true },
password: { type: "string", required: true } },
beforeCreate: function(values, next) { next(); } };

Sails.js 0.10.0-rc5 many-to-many association: remove

i'm developing an app with sails.js beta and mongodb.
I've two models in a many-to-many association, i can successfully associate and populate instances of these models using .add() and .populate() methods. My problem is now that the .remove() method seems to do nothing.
here the models:
//Menu.js
module.exports = {
schema : true,
attributes: {
name: {
type: 'string',
minLength: 3,
required: true
},
dishes: {
collection: 'dish',
via: 'menus',
dominant: true
}
}
};
//Dish.js
module.exports = {
schema : true,
attributes: {
name: {
type: 'string',
minLength: 3,
required: true
},
description: 'string',
menus: {
collection: 'menu',
via: 'dishes'
}
}
};
And here the controller actions...
addDishToMenu: function(req,res,next){
Menu.findOne(req.param('menu')).populate('dishes').exec(function(err,bean){
if(err) return next(err);
if(!bean) return next();
bean.dishes.add(req.param('dish'));
bean.save(function(err) {
if(err) return next(err);
res.redirect('/main/dishes/');
})
})
},
removeDishFromMenu: function(req,res,next){
Menu.findOne(req.param('menu')).populate('dishes').exec(function(err,bean){
if(err) return next(err);
if(!bean) return next();
bean.dishes.remove(req.param('dish'));
bean.save(function(err) {
if(err) return next(err);
res.redirect('/main/menu/' + req.param('menu'));
})
})
}
I can't figure out what i'm doing wrong. Any ideas?
This issue has been fixed and I confirmed it with the repo I sent earlier. If you update your sails, waterline, and sails-mongo versions you should be good to go.