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

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'));
}
},

Related

Node.js - CRUD API multi delete ID's from SQL

I have small project with ReactJS + NodeJS + mySQL.
I can't create-receive correct request for multi delete by IDs.
This how I sent request from React to Node ==>
const deleteProductsByIds = () => {
let ids = [];
stateProducts.forEach((d) => {
if (d.select) {
ids.push(d.id);
}
});
axios
.delete(`http://localhost:5000/products/${ids}`)
.then((data) => {
console.log(data);
getProducts();
})
.catch((err) => alert(err));
};
this how I receive request in Node(sequelize)
router.delete('/:ids', deleteProducts);
export const deleteProducts = async (req, res) => {
try {
await Product.destroy({
where: {
id: []
}
});
res.json({
"message": "ProductS Deleted"
});
} catch (error) {
res.json({ message: error.message });
}
in logs I have this data and by message everything fine, but products(301,302,303,304) not deleted.
config: {url: 'http://localhost:5000/products/301,302,303,304',
method: 'delete', headers: {…},
transformRequest: Array(1), transformResponse: Array(1), …}
data: {message: 'ProductS Deleted'}
I try
where: {
id: req.params.ids
}
but ids value undefind
also I try:
const ids = req.params
try {
await Product.destroy({
where: {
id: ids
}
});
message: "Invalid value { ids: '301,302,303,304' }"}
but receive error message.
usual delete request by ID working without any problem.
For example:
export const deleteProduct = async (req, res) => {
try {
await Product.destroy({
where: {
id: req.params.id
}
});
res.json({
"message": "Product Deleted"
});
} catch (error) {
res.json({ message: error.message });
}
}
Please help me, because I can't find so much information about multi delete request with React-Node-mySQL.

Sequelize is not throwing error for invalid inputs in findAll and findOne methods

I have built a nodejs express app that uses sequelize as ORM to handle MySQL transactions. There are no issues in validations for create, update and delete requests however if I try to fetch data using the findOne and findAll method sequelize seems to escape to validate data.
I have tried writing implicit validations for sequelize using validate but it still doesn't work.
This is the code :
getTradeOrder: async (params) => {
try {
// for params: {amount: '500jha'}
// tradeorder is fetched as if the amount's value was 500
let data = await TradeOrder.findOne({ where: params });
// returns data:{id:2, user:"gfa7834djksfyui32", amount:500, ...}
return { status: 200, error: null, data: data };
} catch (err) {
console.log(err);
return {
status: 400,
error: err.message,
};
}
},
listAllTradeOrders: async (params) => {
try {
// for params: {amount: '500jha'}
// tradeorders are fetched as if the amount's value was 500
let tradeOrders = await TradeOrder.findAll({
where: params,
});
// returns tradeorders:[{id:2, user:"gfa7834djksfyui32", amount:500, ...}, ...]
return { status: 200, error: null, data: tradeOrders };
} catch (err) {
console.log(err);
return {
status: 400,
error: err.message,
};
}
},
};
This is the model :
const tradeOrderSchema = {
id: DataTypes.NUMBER,
user: DataTypes.STRING,
amount: DataTypes.NUMBER,
paymentMode: DataTypes.STRING,
units: DataTypes.NUMBER,
bankName: DataTypes.STRING
...
Ideally, sequelize should capture the invalid value and throw an error for invalid value of amount.
If anyone knows why it is not happening or how to add implicit validation except for validate please let me know.

Convert MySQL update query into sequelize query

UPDATE `users` SET tempToken=tempToken-"5" WHERE `id`="1"
How can I write this query into sequelize query.
For an async function, this is how you would do it, assuming you've set up your User model:
myFunction: async (req, res) => {
var tempToken = req.body.tempToken // Put whatever your data source is here for tempToken
var newValue = tempToken - 5
try {
await User.update({
tempToken: newValue
},
{
where: [{
id: 1
}]
})
res.status(200).send();
}
catch (error) {
res.status(500).send(error);
}
}
or
myFunction: async (req, res) => {
try {
const user = User.findOne({
where: {
id: 1
}
})
await user.update({
tempToken: user.tempToken - 5
})
res.status(200).send();
}
catch (error) {
res.status(500).send(error);
}
}
Also, don't forget to 'require' the user model in the .js file that you use this function in.

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 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.