Include Model with Group - Sequelize/NodeJS - node.js

I have this problem, and i cant solved that.
I need get the name form 'competenciaId' in another model.
const data = await FuncionariosCompetencias.findAndCountAll({
attributes: ['competenciaId',
sequelize.fn('count', sequelize.col('competenciaId'))],
include: [
{ model: Competencia, attributes: [] }
],
group: ['competenciaId', 'Competencia.competencia']
})
.then(function (data) {
return data;
})
.catch(error => {
return error;
});
res.json({ success: true, data: data });
If i removed the "includ:" i have the result but i need name to show it
var Funcionario_Competencias = sequelize.define('funcionarios_competencias', {
nivelcomp: {
type: Sequelize.INTEGER
}
},
{
timestamps: false
})
Funcionario_Competencias.belongsTo(Competencia)
Funcionario_Competencias.belongsTo(Funcionario)

Related

Cannot save object of array input data into mongodb

how I update my array data in nested array in node js and mongo db. when i was try to save data then massage was print but data not saved in mongo db, please check schema and back end code explain which sentence to create a problem.
// schema
mainmenu: [
{
arrname: String,
submenuarray: [
{
dishname1: {
type: String,
},
prize1: {
type: Number,
},
dishcategory1: {
type: String,
},
},
],
},
];
// back End
app.patch('/addsubmenu/:id/:mainid', async (req, res) => {
const mainid = req.params.mainid;
console.log(mainid);
const id = req.params.id;
console.log(id);
getschema
.findByIdAndUpdate(
{ _id: mainid, 'submenuarray._id': id },
{
$push: {
submenuarray: {
dishname1: req.body.dishname1,
prize1: req.body.prize1,
dishcategory1: req.body.dishcategory1,
},
},
}
)
.then((data) => {
console.log(data);
res.status(201).json(data);
})
.catch((err) => {
console.log(err);
});
});
The findByIdAndUpdate accept the id as first parameter, try to use findOneAndUpdate.
Also, set the flag { new: true} to return the updated object:
getschema
.findOneAndUpdate(
{ _id: mainid, 'submenuarray._id': id },
{
$push: {
submenuarray: {
dishname1: req.body.dishname1,
prize1: req.body.prize1,
dishcategory1: req.body.dishcategory1,
},
},
},
{ new: true }
)
.then((data) => {
console.log(data);
res.status(201).json(data);
})
.catch((err) => {
console.log(err);
});

nodejs sequelize map reponse

I have an API that should return an array, good but my result each array has more than 3 objects so I need to map them and I did it doing it in the back end
async function getAllProduct(req,res) {
try {
const results = await Products.findAll({
// raw: true, <= remove
attributes:['id','name', 'float', 'price'],
include: [{
model: SubCategory,
as: 'subcategory',
attributes: ['id','name'],
},
{
model:Exteriors,
as: 'exteriors',
attributes: ['id','name']
},
{
model:Types,
as: 'types',
attributes: ['id','name']
},
],
})
results.map( (products) => {
const model = {
id: products.id,
name: products.name,
float: products.float,
price: products.price,
id_sub: products.subcategory.id,
subcategory: products.subcategory.name,
id_types: products.types.id,
type: products.types.name,
id_ext: products.exteriors.id,
exterior: products.exteriors.name,
}
listProducts.push(model);
})
if(listProducts){
return res.status(200).json({listProducts})
}
else{
return res.status(400).json({result: 'failed to get Products'})
}
} catch (error) {
console.error(error);
}
}
it would be better to map the result to the front end or already send mapped, and how could I narrow down this path to fetch the data from the front

Join or Populate Query In Sequelize

Initially i was using mongoDb to access or manipulate database. But now I want to shift to mySQL but then I used Sequelize ORM to get or set data. But I am having problem in joining or populating 2 tables together to show the data on screen
I have already include attribute to get whole data but I failed
Warehouse.findAll( { raw: true } ).then( warehouses => {
Location.findAll( { raw: true }, { include: { model: Warehouse } } ).then( locations => {
const locationObject = locations.map( loaction => {
return Object.assign( {}, {
location_code: loaction.location_code,
location_name: loaction.location_name,
location_created_on: loaction.location_created_on,
isActive: loaction.isActive,
location_warehouse: warehouses.map( warehouse => {
return Object.assign( {}, {
warehouse_code: warehouse.warehouse_code,
warehouse_name: warehouse.warehouse_name,
} )
} )
} )
} )
console.log( "locations---------------", locations )
if ( locations == null )
return res.status( 422 ).send( { header: "Error", content: "err-msg.NoData" } );
else {
Location.count().then( counts => {
if ( err ) {
res.status( 422 ).send( { header: "Error", content: "err-msg.NoData" } );
} else {
res.send( {
success: true,
msg: resp = {
locations,
counts
}
} );
}
return;
} );
return;
}
res.json( locationObject );
} );
} )
schema i used
module.exports = function () {
const Sequelize = require( 'sequelize' );
const { db } = require( '../../Config/config' );
const sequelize = new Sequelize( db.url , '*********',, '*********', {
host: '*********',,
port: '3306',
dialect: 'mysql',
operatorsAliases: false,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
define: {
timestamps: false
}
} );
const Warehouse = sequelize.define( 'warehouses', {
warehouse_code: {
type: Sequelize.STRING,
primaryKey: true
},
warehouse_name: Sequelize.STRING,
} );
const Location = sequelize.define( 'locations', {
location_code: {
type: Sequelize.STRING,
primaryKey: true
},
location_name: Sequelize.STRING,
location_warehouse: {
type: Sequelize.STRING,
references: 'warehouses', //table name
referencesKey: 'warehouse_code' // column name in the table
}
} );
Warehouse.hasMany(Location , {foreignKey: 'location_warehouse', sourceKey: 'warehouse_code'});
Location.belongsTo(Warehouse , {foreignKey: 'location_warehouse', targetKey: 'warehouse_code'});
return {
models: {
Location,
Warehouse,
}
}
}
I want Warehouse name in my location table where i have linked location table with warehouse_code.
I got the solution to the problem. All i need to do is
{ include: [ { model: Warehouse, as: 'warehouse' } ] }
While I was giving:
{ raw: true }, { include: { model: Warehouse }}
there was a missing square brackets within include statement
Location.findAll( { include: [ { model: Warehouse, as: 'warehouse' } ] } ).then( locations => {
if ( locations == null )
return res.status( 422 ).send( { header: "Error", content: "err-msg.NoData" } );
else {
Location.count().then( counts => {
res.send( {
success: true,
msg: resp = {
locations,
counts
}
} );
return;
} );
return;
}
} );

sequelize.js association accessor

I made API server with Node.js
Also I use sequelize.js(version 4) for communicate with MySQL.
My table structure is here.
[Article]
no(PK)
subject
content
created_at
updated_at
[Comment]
no(PK)
content
created_at
updated_at
article_no(FK to Article)
[index.controller.js]
import { Article, Comment } from '../model/model';
export const index = (req, res) => {
res.send('controller index');
};
export const getArticle = (req, res) => {
try {
Article.all()
.then(article => {
res.status(200).json({status: true, result: article});
});
} catch(e) {
res.status(500).json({status: false, result: "get article fail"});
}
}
export const addArticle = (req, res) => {
const { subject, content } = req.body;
try {
Article.create({
subject: subject,
content: content
})
res.status(200).json({status: true, result: "article write success"});
} catch(e) {
res.status(500).json({status: false, result: "article fail"});
}
}
export const getComment = (req, res) => {
try {
Comment.all()
.then(comment => {
res.status(200).json({status: true, result: comment})
});
} catch(e) {
res.status(500).json({status: false, result: "get comment fail"});
}
}
export const addComment = (req, res) => {
const { content, article_no } = req.body;
try {
Comment.create({
content: content,
article_no: article_no
})
.then(() => res.status(200).json({status: true, result: "comment write success"}))
} catch(e) {
console.log(e);
res.status(500).json({status: false, result: "comment fail"});
}
}
[index.js]
import express from 'express';
import { index, getArticle, getComment,addArticle, addComment } from './index.controller';
const router = express.Router();
router.get('/', index);
router.get('/article', getArticle);
router.post('/article', addArticle);
router.get('/comment', getComment);
router.post('/comment', addComment);
export default router;
[model.js]
import Sequelize from 'sequelize';
const sequelize = new Sequelize('db', 'id', 'pw', {
host: '127.0.0.1',
dialect: 'mysql'
})
export const Article = sequelize.define('article', {
no: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
subject: {
type: Sequelize.STRING,
allowNull: false
},
content: {
type: Sequelize.STRING,
allowNull: false
}
}, {
freezeTableName: true,
underscored: true
})
export const Comment = sequelize.define('comment', {
no: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
content: {
type: Sequelize.STRING,
allowNull: false
}
}, {
freezeTableName: true,
underscored: true
})
Article.hasMany(Comment, {as: 'Comments'}); // association
Comment.belongsTo(Article); // association
sequelize.sync({
force: false
});
Because of association(hasMany, belongsTo), article_no column will be added to Comment table.
Refer to this document, http://docs.sequelizejs.com/manual/tutorial/associations.html#one-to-many-associations-hasmany-
It says that Instances of Project will get the accessors getWorkers and setWorkers.
In my case, it will be getComments and setComments.
But I don't know exactly how can I get all the comments related articles with using accessor.
Current output is here. (If I connect to GET /article)
{
"status":true,
"result":[
{
"no":1,
"content":"comment test",
"created_at":"2018-07-18T05:00:45.000Z",
"updated_at":"2018-07-18T05:00:45.000Z",
"article_no":1
}
]
}
Desired output is here
{
"status":true,
"result":[
{
"no":1,
"content":"comment test",
"created_at":"2018-07-18T05:00:45.000Z",
"updated_at":"2018-07-18T05:00:45.000Z",
"article_no":1,
"comments": [
// related comments here!
]
}
]
}
Thanks.
When you want to join another model you should use include in your query
User.findAll({
include: [
{ model: Profile, required: true // inner join }
],
limit: 3
});
Check out the Sequelize model usage docs.
To access the comments with accessors you will need do something like this:
const articles = await Article.all();
articles.forEach(article => {
const comments = await article.getComments();
})
The idea behind is that each article sequelize object will have the accessor getComments but internally what it does when you execute getComments it makes a new request to the database with the prepopulated articleId in the comments where query. This is called lazy loading because you can load the data when you need it. But that is not your case.
For the desired output I suggest to use the include method cause it will make a single request to the database.

Sailsjs update model json

Let's say there is a a user model defined like this.
...
attributes: {
properties: {
type: 'json',
required: true,
defaultsTo: {
canEdit: {
owned: false,
other: false
}
}
}
}
How can I update user.properties.canEdit.owned and user.properties.canEdit.other?
It can be done this way.
User
.findOne()
.where({ ... })
.then(function(user) {
user.properties.canEdit.owned = true;
user.properties.canEdit.other = false;
user.save(function(err) { ... });
});

Resources