I have two model
Account.js and Content.js
In content.js i have associated Account model like this
module.exports = {
attributes: {
title: { type: "string" },
description: { type: "string" },
userId: { model: "account", required: true },
categoryId: { model: "contentcategory" },
},
};
In account.js model file
i have
module.exports = {
attributes: {
fName: { type: "string" },
lName: { type: "string" },
pass: { type: "string", required: true },
email: { type: "string", required: true, isEmail: true, unique: true },
phone: { type: "number" },
walletBalance: { type: "number", defaultsTo: 0 },
},
};
When fetching the a content I get list of content that also includes account details.
{
title:"category Name",
description : "CAtegort Desc",
userId : {
id: 12552,
fName:John,
lName:Doe,
pass : "23623562356",
email:"john Doe",
phone: "124151516",
walletBalance: 234
}
}
I want only the fname and lname of the user and hide pass, walletbalance etc, how can i do it sails waterline
You have to use customToJSON as mentioned in the docs.
with the following sentence to hide unwanted fields in account.js:
customToJSON: function () {
return _.omit(this, ['pass', 'email', 'phone', 'walletBalance'])
},
Add it after model's attribute object.
Related
I try to create new collection with mongodb.
I wrote the MongoDB shcema, Nodejs+express code and everything work fine until I send parameters with Json inside them.
I was created this schema (and also more code under this schema) but its not work and I got error:
const partySchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
title: { type: String, required: true },
datetime: { type: Date, required: true },
location: {
scraping_location: { type: String, required: true },
display_location: { type: String, required: false },
city: { type: String, required: false },
adress: { type: String, required: false },
area: { type: String, required: false }
},
picture: { type: String, required: true },
url: { type: String, required: true },
affiliate_url: { type: String, required: true },
music_by: {type: [], required: false },
music_type: {type: [], required: false },
min_age_for_men: {type: Number, required: true },
min_age_for_women: {type: Number, required: true },
status_check: {type: Boolean, default: false },
tags: {
concept: { type: String, required: false },
free_text: { type: [], required: false }
},
producer_id: { type: String, required: false },
});
and the code that I wrote with nodejs+express is this:
const { title, datetime, location, picture, url, affiliate_url, music_by, music_type, min_age_for_men, min_age_for_women, tags, producer_id } = req.body;
const party = new Party({
_id: new mongoose.Types.ObjectId(),
title,
datetime,
location: { scarping_location: location.location_scarping },
picture,
url,
affiliate_url,
music_by,
music_type,
min_age_for_men,
min_age_for_women,
tags,
producer_id
});
party.save().then(() => {
res.status(200).json({
message: 'Create a new user'
})
}).catch(error => {
res.status(500).json({
error
})
});
when I send reqeust to the api with this body:
{
"title": "test",
"datetime": "2002-07-15T10:00:00+0300",
"location": {
"location_scarping": "new york"
},
"picture": "test.jpg",
"url": "https://google.com",
"affiliate_url": "https://google.com",
"min_age_for_men": 18,
"min_age_for_women": 16
}
I got this error:
{
"error": {
"errors": {
"location.scraping_location": {
"name": "ValidatorError",
"message": "Path `location.scraping_location` is required.",
"properties": {
"message": "Path `location.scraping_location` is required.",
"type": "required",
"path": "location.scraping_location"
},
"kind": "required",
"path": "location.scraping_location"
}
},
"_message": "Party validation failed",
"name": "ValidationError",
"message": "Party validation failed: location.scraping_location: Path `location.scraping_location` is required."
}
}
why its happend?
Looks like this is just a typo, from your schema:
scraping_location: { type: String, required: true }
You're trying to insert: location_scarping not location_scraping
"location_scarping": "new york"
Hopefully that fixes it.
I have model
username: {
type: String,
required: true,
},
firstname: {
type: String,
},
lastname: {
type: String,
},
email: {
type: String,
required: true,
},
comments: [
{
name: {
type: String,
},
text: {
type: String,
},
},
],
And I want update userModel using Controllers this.router.patch(${this.path}/:id, this.editProfile);
const user = await userModel.findByIdAndUpdate(
req.params.id,
{
...req.body,
},
{ new: true, runValidators: true },
);
return res
.status(StatusCodes.OK).send(user)
Everything works but the problem is when I update comments:
When I sent req "comments": [
{
"name": "coment",
"text":"text"
}
]
It's okay, but when I update without name
{
"text":"text2"
}
the name disappears, but I want that text2 was updated, and the name still exists. What I should use?
const projectSchema = mongoose.Schema({
title: { type: String, required: true, trim: true },
projectId: { type: String, required: true, trim: true, unique: true },
company: { type: mongoose.Schema.Types.ObjectId, ref: 'Company', required: true },
description: { type: String, trim: true },
remark: { type: String, trim: true },
active: { type: Boolean, required: true },
participants: [{
user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
active: { type: Boolean, required: true },
timeSpent: [{
date: { type: Date, required: true },
hour: { type: Number, required: true }
}]
}]
});
I've searched through a lot of SO questions, but none of them seems to be able to solve my problem. Sometimes I need to update one of the field from one participant, I want to update it in a way that when
//this data to apply update on the first element of the participants array
const partialParticipantUpdate = {
active: false
}
can be easily update to the sub document without rewriting all the other property. Basically like findByIdAndUpdate not findByIdAndReplace. I've tried aggregation but its only for reading data not writing data. I've also tried
let p = await Project.update({
"_id": mongoose.Types.ObjectId("5ee22f90e550c32194fb7a91"),
"participants._id": mongoose.Types.ObjectId("5ee4b5bd4fdcdb0c8813f5f5")
}, {
"$set": { "participants.0": partialParticipantUpdate } })
console.log(p);
However some of the participants property is removed after the update
{
"_id": { "$oid": "5ee22f90e550c32194fb7a91" },
"title": "Geo Chart Example",
"projectId": "myId",
"company": { "$oid": "5ee22ca46c7fc4358ced20a1" },
"description": "asd",
"remark": "re",
"active": true,
"participants": [{
"_id": { "$oid": "5ee4f37f4d8c234cc02d405a" },
"active": false,
"timeSpent": []
},
{
"_id": { "$oid": "5ee4c8a955ed7f23445a3cbc" },
"user": { "$oid": "5ee0bdc318998236706b5e5a" },
"active": true,
"timeSpent": []
}
],
"__v": 0
}
The update did change the first participant's "active" property from true to false, but it also lost some of the property like "user" and "timeSpent" array will get emptied as well
Finally I found the solution
const partialParticipantUpdate = {
active: false
}
let p = await Project.findById("5ee22f90e550c32194fb7a91");
let x = p.participants.id("5ee7224be4e4386084b87d3c");
x.set(partialParticipantUpdate);
let response = await p.save({ validateBeforeSave: false });
console.log(response);
The only downside is that I have to communicate with mongoose twice
I am using a sailsjs framework for an app. I am building, and I am trying to extract the id value from a model I have:
const memoryCreatorId = _(Memory.creator).map('id').value();
console.log(memoryCreatorId);
const message = {
app_id: '***********************',
contents: {"en": "Yeah Buddy, Rolling Like a Big Shot!"},
filters: [{"field": "tag", "key": "userId", "relation": "=", "value": memoryCreatorId}],
ios_badgeType: 'Increase',
ios_badgeCount: 1
};
return PushNotificationService.sendNotification(message);
I'm basically trying to get what would be the Memory.creator.User.id value. So basically the userid of the person who creates a memory. I'm trying to get it from the "Memory" model "creator" attribute, which maps to the "User" model, and from the "User" model, extract the "id" attribute. Thanks for your help in advance!
Memory model below:
Memory.js
const _ = require('lodash');
module.exports = {
attributes: {
creator: {
model: 'User'
},
title: {
type: 'string'
},
description: {
type: 'text'
},
contentUrl: {
type: 'string',
url: true
},
cropRect: {
type: 'string'
},
likers: {
collection: 'User',
via: 'memoryLikes'
},
comments: {
collection: 'Comment',
via: 'memory'
},
update: {
model: 'Update',
},
cause: {
model: 'Cause',
}
}
};
User model is a follows:
User.js
'use strict';
const uuid = require('node-uuid');
const CipherService = require('../services/CipherService');
const BraintreeService = require('../services/BraintreeService');
module.exports = {
attributes: {
id: {
type: 'string',
primaryKey: true,
defaultsTo: () => uuid.v4(),
unique: true,
index: true,
uuidv4: true
},
firstName: {
type: 'string',
defaultsTo: ''
},
lastName: {
type: 'string',
defaultsTo: ''
},
email: {
type: 'string',
email: true,
required: true,
unique: true
},
password: {
type: 'string'
},
passwordResetToken: {
type: 'string'
},
passwordResetTokenExpires: {
type: 'string'
},
type: {
type: 'string',
enum: ['admin', 'member']
},
city: {
type: 'string'
},
state: {
type: 'string'
},
address: {
type: 'string'
},
institution: {
model: 'Institution'
},
major: {
type: 'string'
},
contentUrl: {
type: 'string',
url: true,
defaultsTo: AwsService.getAssetImageUrl('user-default.png')
},
cropRect: {
type: 'string'
},
graduationYear: {
type: 'integer'
},
donations: {
collection: 'Donation',
via: 'donor'
},
memories: {
collection: 'Memory',
via: 'creator'
},
causes: {
collection: 'Cause',
via: 'followers',
dominant: true
},
adminCauses: {
collection: 'Cause',
via: 'admins'
},
isLeader: {
type: 'boolean',
defaultsTo: false
},
isCurrentStudent: {
type: 'boolean',
defaultsTo: false
},
isAdmin: {
type: 'boolean',
defaultsTo: false
},
adminTitle: {
type: 'string'
},
paymentProfile: {
model: 'PaymentProfile'
},
jsonWebTokens: {
collection: 'Jwt',
via: 'owner'
},
memoryLikes: {
collection: 'Memory',
via: 'likers'
},
updateLikes: {
collection: 'Update',
via: 'likers'
},
toJSON: function() {
return User.clean(this);
}
},
beforeUpdate: (values, next) => {
CipherService.hashPassword(values).then(() => next()).catch(next);
},
beforeCreate: (values, next) => {
CipherService.hashPassword(values).then(() => next()).catch(next);
},
clean: (user) => {
//let obj = user.toObject();
delete user.password;
delete user.jsonWebTokens;
delete user.passwordResetToken;
delete user.passwordResetTokenExpires;
return user;
}
};
I've got a user model, and I'm just trying to test out beforeCreate by returning err, but when I do POST /user it creates the model fine, without executing the beforeCreate method. What am I doing wrong here? Here's models/User.js:
module.exports = {
connection: "mysql",
attributes: {
firstname: {
type: "string",
required: true
},
lastname: {
type: "string",
required: true
},
fullname: function() {
return this.firstname + ' ' + this.lastname;
},
username: {
type: "string",
required: true
},
password: {
type: "string",
required: true
},
email: {
type: "email",
required: true
},
status: {
type: "integer",
/*
* 0 - unconfirmed, 1 - confirmed, 2- suspended
*/
enum: [0, 1, 2]
},
// Override toJSON instance method to remove password value
toJSON: function() {
var obj = this.toObject();
delete obj.password;
return obj;
},
// Associations
roles: {
collection: "role",
via: "users"
},
permissions: {
collection: "permission",
via: "users"
},
// Lifecycle Callbacks
beforeCreate: function(values, next) {
return next(err);
}
}
};
beforeCreate is not an attribute but a method on the model, so it should be like this:
attributes: {
....
},
beforeCreate: {
....
}
Your beforeCreate got inside attributes. It have to be on the outside. like -
module.exports = {
connection: "mysql",
attributes: {
firstname: {
type: "string",
required: true
},
lastname: {
type: "string",
required: true
},
fullname: function() {
return this.firstname + ' ' + this.lastname;
},
username: {
type: "string",
required: true
},
password: {
type: "string",
required: true
},
email: {
type: "email",
required: true
},
status: {
type: "integer",
/*
* 0 - unconfirmed, 1 - confirmed, 2- suspended
*/
enum: [0, 1, 2]
},
// Override toJSON instance method to remove password value
toJSON: function() {
var obj = this.toObject();
delete obj.password;
return obj;
},
// Associations
roles: {
collection: "role",
via: "users"
},
permissions: {
collection: "permission",
via: "users"
}
},
beforeCreate: function(values, next){
return next(err);
}
};