I have a service function to get users from my MySQL database using Sequelize ORM and i would to like to append fullName to the Users.
const filterUsers = async ([...users]:IUsers[]) => {
let searchAttributes = {};
if (users) { searchAttributes = { [Op.or]: users }; }
const filteredUsers = await User.findAll({
raw: true,
nest: true,
where: { ...searchAttributes },
include: [{
model: Club,
as: 'homeClub',
}, {
model: Club,
as: 'awayClub',
}] });
return filteredUsers as unknown as IUsersWithTeams[];
};
FilteredUsers response:
filteredUsers =
[
{
id: 1
name: 'John',
LastName: 'Mayer',
homeClub: 'Barcelona',
awayClub: 'Real Madrid',
},
{
id: 2,
name: 'Adam',
LastName: 'Smith',
homeClub: 'PSG',
awayClub: 'Milan',
},
]
What i would like to receive:
const expectedUserResponse = [
{
id: 1
name: 'John',
LastName: 'Mayer',
FullName: 'John Mayer',
homeClub: 'Barcelona',
awayClub: 'Real Madrid',
},
{
id: 2,
name: 'Adam',
LastName: 'Smith',
FullName: 'Adam Smith',
homeClub: 'PSG',
awayClub: 'Milan',
},
]
How can i do that ? Thank you very much if you can help me ;)
You need to use a virtual field, see documentation and my other answer to the similar question. It seems the official documentation has the example that perfectly fits your request:
const { DataTypes } = require('#sequelize/core');
const User = sequelize.define('user', {
firstName: DataTypes.TEXT,
lastName: DataTypes.TEXT,
fullName: {
type: DataTypes.VIRTUAL,
get() {
return `${this.firstName} ${this.lastName}`;
},
set(value) {
throw new Error('Do not try to set the `fullName` value!');
}
}
});
Related
In my current login api, it returns
"user": {
"id": "3e85decc-2af4-436c-8b7f-e276771234f5",
"email": "cccc#cccc.com",
"password": "$xxxxxxxxxx",
"createdAt": "2021-05-14T08:48:31.000Z",
"updatedAt": "2021-05-14T08:48:31.000Z"
},
"token": "xxxxx"
}
I want to remove the password field in my response, so I use delete user.password in my code, but it's not working
/api/users.js
router.post('/login', (req, res, next) => {
passport.authenticate('local', {session: false}, (err, user, info) =>{
if (err || !user) {...}
req.login(user, {session: false}, (err) => {
if (err) {
res.send(err);
}
const token = jwt.sign(user, 'your_jwt_secret');
console.log(user) // show dataValues and _previousDataValues instead of normal JSON object
delete user.password // not working
return res.json({user, token});
});
})(req, res);
});
I tried to log user object for above file, it returns:
users {
dataValues: {
id: '3e85decc-2af4-436c-8b7f-e276771234f5',
email: 'cccc#cccc.com',
password: '$xxxxxxxxxx',
createdAt: 2021-05-14T08:48:31.000Z,
updatedAt: 2021-05-14T08:48:31.000Z
},
_previousDataValues: {
id: '3e85decc-2af4-436c-8b7f-e276771234f5',
email: 'cccc#cccc.com',
password: '$xxxxxxxxxx',
createdAt: 2021-05-14T08:48:31.000Z,
updatedAt: 2021-05-14T08:48:31.000Z
},
_changed: Set(0) {},
_options: {
isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
raw: true,
attributes: [ 'id', 'email', 'password', 'createdAt', 'updatedAt' ]
},
isNewRecord: false
}
This is my user model. I am using Sequelize.
const Sequelize = require('sequelize');
const DataTypes = Sequelize.DataTypes;
const db = require('../sequelize')
let users = db.define('users', {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
allowNull: false,
primaryKey: true
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: 'email'
},
password: {
type: DataTypes.STRING,
},
},
{
hooks: {
beforeCount(options) {
options.raw = false;
}
}
}
);
module.exports = users;
Finally solved it using user.get({plain: true})
let plainUser = user.get({plain: true})
delete plainUser['password']
return res.json({user, token});
It's probably not a good idea to delete properties from the Model directly. Try using ToJSON() to convert the Model to a plain Javascript object and delete the password from that.
plainUser = user.ToJSON();
delete plainUser.password
why dont you re-create your result response, something like this:
let response = {
"user": {
"id": user.dataValues.id,
"email": user.dataValues.email,
"createdAt": user.dataValues.createdAt,
"updatedAt": user.dataValues.updatedAt
},
"token": "xxxxx"
}
JSON.stringify(response)
Try below code in your model to override the sequelize toJSON function
const User = db.define('users', {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
allowNull: false,
primaryKey: true
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: 'email'
},
password: {
type: DataTypes.STRING,
},
},
{
hooks: {
beforeCount(options) {
options.raw = false;
}
}
}
);
User.prototype.toJSON = function () {
const values = Object.assign({}, this.get());
delete values.password;
return values;
};
or using omit() withlodash for cleaner code
User.prototype.toJSON = function () {
const values = {
..._.omit(this.get(), ['password'])
};
return values;
};
I would like to display some information about members, but I don't know how to resolve array of field 'time'. This is array, because it shows their login time. What should I do?
I used GraphQLString, but I am aware of this bad solution.
So I'm getting an error:
"message": "String cannot represent value: [\"12:08\"]",
Here is schema.js
const axios = require("axios");
const {
GraphQLObjectType,
GraphQLString,
GraphQLList,
GraphQLSchema
} = require("graphql");
const memberType = new GraphQLObjectType({
name: "Member",
fields: () => ({
nick: {
type: GraphQLString
},
name_and_surname: {
type: GraphQLString
},
time: {
type: GraphQLString
}
})
});
//Root Query
const RootQuery = new GraphQLObjectType({
name: "RootQueryType",
fields: {
users: {
type: new GraphQLList(memberType),
description: "List of members",
resolve(parent, args) {
return axios
.get("http://25.98.140.121:5000/data")
.then(res => res.data);
}
}
}
})
module.exports = new GraphQLSchema({
query: RootQuery
});
And here is JSON
[
{
"time": [
"12:08"
],
"nick": "Cogi12",
"name_and_surname: "John Steps"
},
{
"time": [
"12:16"
],
"nick": "haris22",
"name_and_surname": "Kenny Jobs"
},
{
"time": [
"12:07",
"12:08",
"12:17",
"12:19",
"12:45",
"13:25"
],
"nick": "Wonski",
"name_and_surname": "Mathew Oxford"
}
]
you can use GraphQLList along with GraphQLString for time type like this,
const memberType = new GraphQLObjectType({
name: "Member",
fields: () => ({
nick: {
type: GraphQLString
},
name_and_surname: {
type: GraphQLString
},
time: {
type: new GraphQLList(GraphQLString)
}
})
});
I am using GraphQL, Sequelize, and MySql to add data to Clients Table. In the GraphQl Mutation, I do the following:
const db = require("./models");
const Mutation = new GraphQLObjectType({
name: "Mutation",
fields: {
addClient: {
type: ClientType,
args: {
lastName: { type: new GraphQLNonNull(GraphQLString) },
firstName: { type: new GraphQLNonNull(GraphQLString) },
primaryPhoneNumber: { type: new GraphQLNonNull(GraphQLString) },
cellphone: { type: GraphQLString },
workPhone: { type: GraphQLString },
email: { type: GraphQLString },
UserId: { type: new GraphQLNonNull(GraphQLString) }
},
resolve(parentValue, args) {
let newClient = new db.Client({
lastName: args.lastName,
firstName: args.firstName,
primaryPhoneNumber: args.primaryPhoneNumber,
cellphone: args.cellphone,
workPhone: args.workPhone,
email: args.email,
UserId: args.UserId
});
console.log(newClient);
return db.Client.create(newClient);
}
}
}
});
But I receive this error back when testing it on GraphiQL:
{
"errors": [
{
"message": "notNull Violation: Client.lastName cannot be null,\nnotNull Violation:
Client.firstName cannot be null",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"addClient"
]
}
],
"data": {
"addClient": null
}
}
I believe this error comes from sequelize as in my Model I define some Non-Null fields:
module.exports = function(sequelize, DataTypes) {
var Client = sequelize.define(
"Client",
{
lastName: {
type: DataTypes.TEXT,
allowNull: false,
len: [1]
},
firstName: {
type: DataTypes.TEXT,
allowNull: false,
len: [1]
},
primaryPhoneNumber: {
type: DataTypes.TEXT,
allowNull: true,
len: [1]
},
cellphone: {
type: DataTypes.TEXT,
allowNull: true,
len: [1]
},
workPhone: {
type: DataTypes.TEXT,
allowNull: true,
len: [1]
},
email: {
type: DataTypes.TEXT,
allowNull: true,
len: [1]
}
},
{
timestamps: false
}
);
Client.associate = function(models) {
// Associating Clients with Pets
// When a Client is deleted, also delete any associated Pets
Client.belongsTo(models.User);
Client.hasMany(models.Pet, {
onDelete: "cascade"
});
};
return Client;
};
This is my query from the front end:
mutation {
addClient(lastName: "ali", firstName: "muhamed", primaryPhoneNumber:
"00990099009", email: "jalimaƱa#email.com", UserId: "14fb9610-4766-11ea-9a4e-
e130bc08c2aa") {
lastName,
firstName
}
}
Does anybody know why is this happening? Any help will be highly appreciated.
Model.create takes a plain object with the values the Model instance should be initialized with. You shouldn't pass an existing instance of Model to it. Instead, just call the save method on the instance.
const instance = new SomeModel({ firstName: 'Bob' })
await instance.save()
This is equivalent to
const instance = SomeModel.build({ firstName: 'Bob' })
await instance.save()
and
await SomeModel.create({ firstName: 'Bob' })
This is my req.body json data from angularjs controller:
{
phoneno: [
{ id: 1, gsm: '123457801', firstName: 'Mohamed', lastName: 'Sameer'},
{ id: 2, gsm: '123450987', firstName: 'Hameed', lastName: 'Basha' }
],
sender: 'ifelse',
message: 'Hello Test'
}
i want to get gsm values from req.body
I want to make the above structure into this type:
[{phoneno:123457801;sender:'ifelse';message:'Hello Test'},{phoneno:123450987;sender:ifelse;message:'Hello Test'}]
then only i am able to insert in mysql.
I think it will helpful to you!...
var body={
phoneno: [
{ id: 1, gsm: '123457801', firstName: 'Mohamed', lastName: 'Sameer'},
{ id: 2, gsm: '123450987', firstName: 'Hameed', lastName: 'Basha' }
],
sender: 'ifelse',
message: 'Hello Test'
};
var new_req_body=[];
for(var i=0;i<body.phoneno.length;i++){
var new_arr={
sender:body.sender,
message:body.message,
phoneno:body.phoneno[i].gsm
};
new_req_body.push(new_arr);
}
console.log(new_req_body);
I have a function which needs to be implemented with Bluebird Promises but unable to work it out. Here is a pseudo code
exports.addEmployees=function (req,res){
var data = [
{
firstName: 'XXXXX',
lastName: 'V',
phone: '9999999999',
dateOfBirth: '2010-08-02',
department: 'IT',
startDate: '2015-08-02',
created: now,
updated: now
},
{
firstName: 'YYYYY',
lastName: 'K',
phone: '8888888888',
dateOfBirth: '2011-08-02',
department: 'IT',
startDate: '2015-08-02',
created: now,
updated: now
},
];
async.each(data, function(item,callback){
req.db.Employee.create(item, callback);
},function(err){
if(err){
res.send("Error!");
}
res.send("Success!");
}
);
}
Thanks
Something like
var Promise = require("bluebird")
var data = [
{
firstName: 'XXXXX',
lastName: 'V',
phone: '9999999999',
dateOfBirth: '2010-08-02',
department: 'IT',
startDate: '2015-08-02',
created: now,
updated: now
},
{
firstName: 'YYYYY',
lastName: 'K',
phone: '8888888888',
dateOfBirth: '2011-08-02',
department: 'IT',
startDate: '2015-08-02',
created: now,
updated: now
},
];
Promise.map(data, function(item) {
return req.db.Employee.create(item)
.then(function(id){ return id })
.catch(MyError, function(e) {
e.item = item;
throw e;
})
}).then(function(idList) {
res.send("Success!");
}).catch(MyError, function(e) {
console.log("Operation failed on " + e.item + ": " + e.message);
res.send("Error!");
});
You need to define myError to make this work (https://github.com/petkaantonov/bluebird/blob/master/API.md#catchfunction-errorclassfunction-predicate-function-handler---promise)
P.S. Sure, req.db.Employee.create(item) should support promises, so probably you will need to promisify it: https://github.com/petkaantonov/bluebird/blob/master/API.md#promisepromisifyallobject-target--object-options---object