error when executing insert with nodejs + sequelize - mysql

I have the following function to insert a record in a MySQL database. I am using NodeJS and Sequelize.
await WeatherData.create ({
control_esp_id: req.body.control_esp_id,
variable_id: req.body.variable_id,
read_date: req.body.date,
value: req.body.value
})
.then ((weatherdata) => {
return res.status (200) .json ({
error: false,
message: "Data regarding the Line / Bay / Room successfully registered!",
weatherdata
});
})
.catch ((err) => {
console.log (err);
return res.status (400) .json ({
error: true,
code: 203,
message: err
});
})
However, the following error message is occurring when I execute the function. i have other inserts and they are working perfectly. Only from this type of model that the error is occurring to me:
TypeError: Cannot read property 'length' of undefined
at WeatherData._initValues (backend/node_modules/sequelize/lib/model.js:140:49)
at new Model (backend/node_modules/sequelize/lib/model.js:118:10)
at new WeatherData (backend/src/app/models/WeatherData.js:9:1)
at Function.build (backend/node_modules/sequelize/lib/model.js:2157:12)
at Function.create (backend/node_modules/sequelize/lib/model.js:2207:23)
at store (backend/src/app/controllers/WeatherDataController.js:62:31)
class WeatherData extends Model {
static init(sequelize) {
super.init({
read_date: DataTypes.DATE,
value: DataTypes.DOUBLE,
}, {
sequelize,
});
return this;
}
static associate(models) {
this.belongsTo(models.ControlEsp, {
foreignKey: 'control_esp_id',
as: 'control_esp',
});
this.belongsTo(models.Variable, {
foreignKey: 'variable_id',
as: 'variable',
});
}
}
sequelizePaginate.paginate(WeatherData);
export default WeatherData
Regards

Related

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

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.

Sequelize can create data but can't get data from Models

I'm unable to understand what actually is wrong with my code. But I know there is a problem in how I'm implementing Promise. As Shipment.findAll() returns a Promise, and I'm creating a promise again for my router to consume.
Then why createShipment is working fine, and getAllShipments is not working.
Controller for Shipment
const Worker = require ('../models').Worker;
const Shipment = require ('../models').Shipment;
function createShipment (shipmentName, shipmentStatus) {
return new Promise ((resolve, reject) => {
Shipment.create({name: shipmentName, status: shipmentStatus})
.then (shipment => resolve(shipment))
.catch (error => reject(error));
});
}
function getAllShipments () {
return new Promise ((resolve, reject) => {
Shipment.findAll()
.then(allShipments => {
console.log(allShipments);
return resolve(allShipments);
})
.catch(error => reject(error))
})
}
module.exports = {
createShipment,
getAllShipments
}
Shipment Router
var router = require('express').Router();
var Shipment = require('./../../../controllers/shipment');
router.post ('/' , (req,res) => {
Shipment.createShipment ('New Shipment', 'Pending')
.then (shipment => {
res.status(200).json({status: true, data: shipment, errors: null, msg: "Shipment Added Successfully"});
})
.catch (error => {
res.status(200).json({status: false, data: {}, errors: error, msg: "Error Creating Shipment. Please see details in Errors Object"});
});
});
router.get('/' , (req, res) => {
Shipment.getAllShipments()
.then(allShipments => {
return res.status(200).status({status: true, data: allShipments, errors: null, msg: "All Shipments fetched successfully"});
})
.catch(error => {
return res.status(200).json({status: false, data: {}, errors: error, msg: "Error Fetching Shipments. Please see details in Errors Object"});
});
})
module.exports = router;
What I'm doing wrong ? Because getAllShipments is giving my output on console but route is not sending response and just waiting and waiting.
Change :
Shipment.getAllShipments()
.then(allShipments => {
return res.status(200).status({status: true, data: allShipments, errors: null, msg: "All Shipments fetched successfully"});
})
to:
return res.status(200).json({status: true, data: allShipments, errors: null, msg: "All Shipments fetched successfully"});
Just a typo and you wrote down a status two times instead of json

Bookshelf cascade delete

I have two models Company and CompanyAdmin. A model Company has many CompanyAdmins. I am trying to delete CompanyAdmins when a parent Company is deleted, using bookshelf plugin bookshelf-cascade-delete. I also use knex to connect mysql db. Here are my models:
const db = bookshelf(connection);
db.plugin(cascadeDelete);
const Company = db.Model.extend({
tableName: 'company',
idAttribute: 'id',
hasTimestamps: true,
company_admins: function () { return this.hasMany(CompanyAdmin); }, // console.log(this);
}, {
dependents: ['company_admins'],
});
const CompanyAdmin = db.Model.extend({
tableName: 'company_admin',
idAttribute: 'id',
hasTimestamps: true,
company: function () { return this.belongsTo(Company) },
});
When I console.log(this) in company_admins function, I get this data:
ModelBase {
tableName: 'company',
idAttribute: 'id',
hasTimestamps: true,
company_admins: [Function: company_admins] }
Here is my DELETE route handler:
.delete((req, res) => {
if (req.user) {
Company.forge({
id: req.user.attributes.company_id,
})
.destroy()
.then(() => {
res.status(200)
.json({
status: 200,
error: false,
});
req.logout();
}).catch((err) => {
console.log(err);
res.status(500)
.json({
status: 500,
error: err.message,
});
});
} else {
res.status(401)
.json({
status: 401,
message: 'User not authenticated',
});
}
});
I am getting this error:
TypeError: Cannot read property 'hasMany' of undefined
Anybody with the same problem?
I solved this. Error was in importing bookshelf.
The code I was using before was:
import bookshelf from 'bookshelf';
const db = bookshelf(connection);
And the correct import of bookshelf look like this:
const db = require('bookshelf')(connection);
Not quite sure why the previous code didn't work, but the modified version works well!

TypeError working with Sails and MySQL

I'm running through this tutorial for Sails, but it uses Mongo and I'd rather use MySQL. Unfortunately this is running me into an error when I try to POST and add a record to the database, but I can't figure out why. It seems to work fine when I use the localDiskDb, but flunks out with MySQL.
The error is:
TypeError: Cannot read property 'name' of undefined
at createCB (/api/controllers/UserController.js:16:52)
UserController.js:
module.exports = {
create: function(req, res){
var params = req.params.all()
User.create({name: params.name}).exec(function createCB(err,created){
return res.json({
notice: 'Created user with name ' + created.name // The error is on this line
});
});
}
};
routes.js:
module.exports.routes = {
'/': {
view: 'homepage'
},
'post /User': 'UserController.create'
};
User.js
module.exports = {
attributes: {
name: {
type: 'string'
}
}
};