Update record using sequelize(mysql) + nodejs - mysql

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
}
})

Related

Sequelize is returning id null instead of the real id when creating a register

When I try to create a new Usuario item Sequelize, it should return the item and the id as a result of the insertion, instead of that, equalize is returning null as id, but the insertion is right in my database.
const Usuario=mysql_db.define('Usuario', {
id_usuario:{
primaryKey: true,
autoIncrement: true,
type: DataTypes.INTEGER(11)
},
identificacion:{
type:DataTypes.STRING
},
nombre: {
type:DataTypes.STRING
},
password: {
type:DataTypes.STRING
},
id_role:{
type:DataTypes.INTEGER
},
activo:{
type:DataTypes.BOOLEAN
},
fecha_creacion:{
type:DataTypes.DATE,
defaultValue:DATE
},
fecha_modificacion:{
type:DataTypes.DATE
}
},{
tableName:'usuarios'
});
Call of Save method ()
const usuariosPost = async (req, res = response) => {
try {
let {identificacion,nombre,password} =req.body;
const usuario= new Usuario({identificacion,nombre,password,activo:'1',id_role:'2'})
usuario.save();
res.json({
msg: 'post API - usuariosPost',
usuario,
});
} catch (error) {
res.status(500).json({
msg:'Comuniquese con el administrador X002'
})
}
}
The primary key is id_usuario and it´s declared with the autoIncrement set in true, and this is the result of the save() method
But i´m completely sure that the insert function in my DB is right as shown below.
You just didn't wait for the result of save call:
await usuario.save();

Sequelize showing error: Unexpected token u in JSON at position 0

I am trying to update a record in mysql database using sequelize but it is not working.
I am getting this error
Unexpected token u in JSON at position 0
Model
module.exports = sequelize.define("branches", {
address: Sequelize.TEXT(),
company: Sequelize.STRING(),
codeConfig: {
type: Sequelize.STRING,
allowNull: false,
get: function () {
return JSON.parse(this.getDataValue('codeConfig'));
},
set: function (val) {
return this.setDataValue('codeConfig', JSON.stringify(val));
}
},
});
Update function
router.put('/:id', async (req, res) => {
const { address, company} = req.body;
try {
const branches = await Branches.findOne({ where: { code: req.params.id } });
if (!branches) return res.json({ msg: "Branch Not Found" });
Branches.update({ "address": "No. 10 distreet street" }, {
where: {
code: "WHJ5uBdriI"
}
}).then(function (newBranch) {
return res.json({ msg: "Updated" });
});
} catch (error) {
console.error(error.message);
res.status(500).send("Server Error");
}
});
Error output
Add autoJsonMap: false, to your sequelize's dialectOptions
Example:
let sequelize = new Sequelize(DATABASE, USER, PASSWORD, {
// some other options
dialectOptions: {
autoJsonMap: false,
}
});
Reference:
https://github.com/sequelize/sequelize/issues/12583
i have noticed that before sequelize make a field update, it fetches through all fields, and then execute a getter function if exist, so for that i added an if check inside a getter, here is the code now the model.update working:
get: function () {
if(this.getDataValue('codeConfig') !== undefined){
/// appentely sequelize tried to parse the value of 'codeConfig' but its undefined since you are updating only address field.
return JSON.parse(this.getDataValue('codeConfig'));
}
},

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})

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

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>

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.