Mongoose / NodeJS - String from db is retrieved but considered as not defined - html

Here's my problem now:
I query a findOne and populate on my DB in order to retrieve an array of string to use in my .EJS but the log says that the value is not defined but its give the value name : "stringName is not defined"
I must have missed something..
This is the User schema :
var UserSchema = new mongoose.Schema({
username: { type: String, required: true, index: {
unique: true } },
email: { type: String, required: true, index: {unique: true } },
password: { type: String, required: true },
tables: [{ type: Schema.Types.ObjectId, ref: 'Table' }],
resetPasswordToken: String,
resetPasswordExpires: Date,
uuid: String,
});
This is the Table schema :
var TableSchema = Schema({
name: { type: String, required: true, index: { unique: true }},
logos: [{ type: Schema.Types.ObjectId, ref: 'Logo'}],
});
This is where I do the query and send the document to the .ejs page:
app.get('/dashboard/:uuid', function(req, res){
if (req.user && userId != "")
{
var query = User.findOne({username: req.user.username}).populate('tables').select('tables');
query.exec(function (err, tables){
if (err) return console.error(err);
console.log (tables.tables[0].name); // Return the right string name
res.render('./pages/dashboard.ejs', {username: req.user.username, tables: tables.tables});
});
}
else
res.redirect('/');
});
And this is the script in ejs that is supposed to render the table names in my page:
<script>
$(document).ready(function (){
<% for(var i = 0; i < tables.length; i++) {%>
var newTab = "<div class=\"square\" style=\"display: inline-block\"><span style=\"margin-top: 50%; text-align: center\">" + <%=tables[i].name%> + "</span></div>";
$(newTab).appendTo('.jumbotron');
<%}%>
});
</script>
If you guys could enlighten up a bit my way that would be so great !

Take a look at this implementation, this is how i would query schema, in firs example we reuse req.user (good), in second we make 2 database calls (bad). In your example you make 1 database call but not populating Logo field of table schema (bad).
app.get('/dashboard/:uuid', function(req, res){
// first example
// no need to query users, you already have tables field
if (!req.user) // what is userId, why you check it
// add `err` checks
return res.redirect('/');
TableSchema
.find({ _id: { $in: req.user.tables } })
.populate('logos', 'url'); // Logo schema fields
.exec(function(err, result_tables){
res.render('./pages/dashboard.ejs', {username: req.user.username, tables: result_tables});
});
// or second example
// if you still for some reason cannot use req.user.tables field
// but strongly recommend to use first one
User.findById(req.user._id, 'tables')
.exec(function (err, user_tables){
// add `err` checks
TableSchema.populate(user_tables, { path: 'logos', model: 'Logo' }, function (err, result_tables){
// add `err` checks
res.render('./pages/dashboard.ejs', {username: req.user.username, tables: result_tables});
});
});
});
As per your comment
in chrome browser : " Uncaught ReferenceError: stringName is not defined " (stringName = what's in tables[0].name)
Try to use forEach operator
<script>
$(document).ready(function (){
<% tables.forEach(function(table){ %>
var newTab = "<a ommited><%= table.name %></a>"; //notice: no `"`
$(newTab).appendTo('.jumbotron');
<% }) %>
});
</script>

Related

Update record using sequelize(mysql) + nodejs

My table name: TIME
My table data fields:
start : 10.00am
stop: null
Now i want to update null as current date
exports.updateGroup = function (req, res) {
Time.update(req.body, {
stop: new Date(),
where: {
id: req.body.id
}
}).then(data => {
return res.status(200).send(data);
}).catch(Sequelize.ValidationError, err => {
return res.status(422).send(err.errors[0].message);
}).catch(err => {
return res.status(400).send(err.message);
});
};
Now its showing same as null after update
My req.body: { mainId: 1, start: '', stop: '' }
my Time model :
var Time = sequelize.define('time', {
start: Sequelize.DATE,
stop: Sequelize.DATE,
});
Firstly, you pass wrong id since there is not a req.body.id property based on body format you've posted.
Secondly, the update method gets two arguments as referenced at official sequelize documentation.
This should work:
Time.update({
start: req.body.start,
stop: req.body.stop
}, {
where: {
id: req.body.mainId
}
})

Updating sub array in JSON with a REST API in Mean Stack

I'm developing a MEAN stack application and I'm hung up on how to actually update a document that has been saved into the MongoDB already. I've seen that I have to use patch instead of post in my REST API paths, but it's still a little clouded to me. I want to insert a new Package into the Package JSON Array in the User JSON.
Possible Duplicate, but he's overriding a value in the array and not adding a new object into it.
My JSON Schema:
//User schema
const UserSchema = mongoose.Schema({
name: {
type: String
},
email: {
type: String,
require: true
},
username:{
type:String,
required: true
},
password:{
type:String,
required: true
},
packages: [{
from: String,
to: String,
tracking: String
}]
});
My REST API Paths
//Update
router.patch('/update', (req, res) => {
const username = req.body.username;
const packages = req.body.packages;
User.getUserByUsername(username, (err, user) => {
if(!user){
return res.json({success: false, msg: 'User not found'});
} else {
User.addPackages(user, req.body.packages, (err, user) => {
if(err){
res.json({success: false, msg:'Failed to update packages'});
} else {
res.json({success: true, msg:'update packages'});
}
})
}
});
});
My Module's:
module.exports.addPackages = function(user, packages, callback){
User.findOneAndUpdate(
{username:user.username},
{$push: {"packages" : {
"to" : packages.to,
"from" : packages.from,
"tracking" : packages.tracking
}}},
{new:true},
function(err, newPackage){
if (err) throw err;
});
}
module.exports.getUserById = function(id, callback){
User.findById(id, callback);
}
module.exports.getUserByUsername = function(username, callback){
const query = {username: username}
User.findOne(query, callback);
}
They're updating into my MongoDB, but just the object ID and not the values...
db.your_collection.update({},
{$set : {"new_field":1}},
{upsert:false,
multi:true})

how to update user table in node js

mycode is--
updateUser: function(req, res) {
var data = req.body;
var option = {
name: data.name,
mobile: data.mobile,
domain: data.domain,
}
userModel.update(option, function (error, rows) {
console.log('###############',error || rows);
if(!res){
//TODO: Error handling
console.log("ERROR", res);
res.status(200).send({"status_code": 0, 'message': 'Some error occured'});
return;
}
res.status(200).send({"status_code": 1, 'message': 'Succesfully Updated'});
})
},
the problem is updated all user coloumn.
in the code how to give id of the particular update data.
If you are not writing some very low level driver, I would recommend to use ORM like https://github.com/sequelize/sequelize. The very first example on their homepage shows:
var Sequelize = require('sequelize');
var sequelize = new Sequelize('database', 'username', 'password');
var User = sequelize.define('user', {
username: Sequelize.STRING,
birthday: Sequelize.DATE
});
sequelize.sync().then(function() {
return User.create({
username: 'janedoe',
birthday: new Date(1980, 6, 20)
});
}).then(function(jane) {
console.log(jane.get());
jane.update({
username: 'a very different username now'
}).then(function() {
console.log(jane.get());
})
});
You should use Bookshelf.js, good ORM, easy to use

Sailjs-Waterline: Serialize, Parse and initialize an Model

Let's assume that I found user using next command:
User.findOne(id).exec(function(err, user){
redis.set(JSON.stringify(user), id);
})
After that I'm loading from redis my object
redis.get(id, function(err, reply){
if(!err && reply) {
var user = JSON.parse(reply);
// here methods like user.save() or any of defined manually by developer is unavailable
//
} else {
..
}
})
User model example:
module.exports = {
attributes : {
// Simple attribute:
// name: 'STRING',
// Or for more flexibility:
// phoneNumber: {
// type: 'STRING',
// defaultValue: '555-555-5555'
// }
email : {
type: 'string',
unique: true
},
// ...
verifyPass: function(pass, callback) {
var obj = this.toObject();
if (callback) {
return Password.compare(pass, obj.local.password, callback);
}
return Password.compareSync(pass, obj.local.password);
},
// retrieve profile for sending to front end
getProfile: function() {
var obj = this.toObject();
var profile = {};
profile.id = obj.id;
// ...
return profile;
},
I need all of that methods to be work whenever I parse waterline model from json. Is there a way to initialize it without triggering db at all. Also would be nice if I could to call user.save().
There's currently no documented public API for this unfortunately, but you can use,
var user = new PersonCollection._model(values, {showJoins: true});
See how that works for you!

How do you mock MySQL (with node-orm2) in Node.js/Express?

I am using node.js/express with https://github.com/dresende/node-orm2 to use my MySQL database.
I am new to the node.js world and I am quite stuck so far, I don't know how to unit test (not integration test) a simple function.
Here is my server.js, loading my user model (ORM)
var express = require('express'),
orm = require('orm'),
config = require('./config/config.js'),
auth = require('./services/authentication'),
helper = require('./middlewares/helper.js'),
friends = require('./modules/friends.js');
var app = express();
app.use(orm.express('mysql://' + config.mysql.username + ':' + config.mysql.pwd + '#' + config.mysql.host + ':' + config.mysql.port + '/' + config.mysql.db, {
define: function(db, models, next) {
db.load("./models/models.js", function(err) { // loaded!
models.user = db.models.user;
});
}
}));
var middlewares = [auth.authenticate, helper.retrieveUser];
app.get('/friends', middlewares, friends.findActiveFriends);
app.listen(3000);
console.log('Listening on port 3000...');
here is the user model :
module.exports = function (db, cb) {
var User = db.define('user', {
uid : { type: 'number', rational: false, unique: true, required: true },
first_name : { type: 'text', size: 100, required: true },
last_name : { type: 'text', size: 100, required: true },
picture : { type: 'text', size: 255, required: false },
email : { type: 'text', size: 255, required: true },
creation_date : { type: 'date', time: true },
modification_date : { type: 'date', time: true }
}, {
methods: {
fullName: function () {
return this.first_name + ' ' + this.last_name;
}
},
hooks: {
beforeCreate: function (next) {
if (this.creation_date == undefined) {
this.creation_date = new Date();
}
if (this.modification_date == undefined) {
this.modification_date = new Date();
}
return next();
}
}
});
// CUSTOM FUNCTIONS
User.getByUid = function(uid, callback) {
this.find({ uid: uid }, function(err, users) {
if(err) callback(err);
if (users.length == 1) {
callback(null, users[0]);
} else {
callback('No user found with uid=' + uid);
}
});
};
User.hasMany("friends", User, {
status: { type: 'enum', values: ['pending', 'refused', 'active'] }
}, {
reverse: 'friendsrev', mergeId: 'user_id', mergeAssocId: 'friend_id'
});
return cb();
};
and here is my methods to find active friends in friends.js:
var _findActiveFriends = function(req, res) {
req.currentUser.getFriends({
status: 'active'
}, function(err, friends) {
if (err) throw err;
res.send(JSON.stringify(friends));
});
};
I would like to know how can I write a simple test (with mocha and sinon.js ?) by mocking the database connection and the request also. I need to mock the value of req.currentUser which is a user returned by the ORM in a middleware.
I just want to run unit tests and do not use a real DB or make some HTTP calls.
thanks for your help.
If you want to mock the req using sinon.js, you can do something like the following.
var sinon = require('sinon');
var friend = require('./friend');
it('some test', function(done) {
var req = {
currentUser: {
// Add all the properties/functions that you are concerned with here.
// and you can/should wrap them around sinon.spy().
// If you are not concerned with that function (i.e. you are not using it)
// then you can simply use sinon.stub() to return a stub function.
}
};
var res = {
send: sinon.spy(function(obj) {
assert.ok(obj); // yes object exists
done(); // end of test
};
};
var next = function() {};
friend.findActiveFriend(req, res, next);
});
This way you shouldn't be connecting to the model, which tests friend.js only.
Also, since I just noticed you are using orm.express, you may also want to simply mock req.models with the stubbed function you desire as above.