Add data to returned model sequelize - javascript

I have a sequelize model object that is working like expected.
const part = sequalize.define("part", {
id: {type:Sequalize.INTEGER, primaryKey: true, autoIncrement: true},
part_number: {type : Sequalize.STRING(12), unique: true, allowNull: false},
description: {type : Sequalize.STRING(255), allowNull: false}, true}
})
But I want to run an additional function when this model is called for example in a query.
I have this function now:
part.prototype.getTotalStock = function () {
let _this = this;
return new Promise(function(resolve, reject) {
part.findOne({
where: {id: _this.id},
include: [{
model: sequalize.models.location,
}]
}).then(result => {
if (result) {
var totalStock = 0;
let stockOnLocation = result.dataValues.locations
stockOnLocation.forEach(function (entry) {
totalStock += entry.stock.amount
});
_this.setDataValue('totalStock', totalStock);
return resolve(_this)
} else {
return resolve(0)
}
}).catch(err => {
return reject(err)
});
})
}
What i'm doing is that I do a query so I have 1 part object. After that I can call:
queryResult.getTotalStock().then(result => {
//data here in result
})
That is working, its retrieving the stock, calculating it, and it is adding the data to self. Now my question, is it possible to append the result of getTotalStock automatically when the model is being used? So that I don't have to call getTotalStock on the returned object?

Related

My object javascript is not fully sent to the back

I'm trying to send an object from front to back.
this is my function :
export const addComponent = (newComponent, inputFields) => (dispatch) => {
const url = process.env.REACT_APP_ADD_COMPONENT;
var componentBody = {
type: newComponent.type,
name: newComponent.name,
};
var componentTest = inputFields.map((inputField) => {
return Object.defineProperty(componentBody, inputField.property, {
value: inputField.content,
});
});
console.log(componentTest);
axios
.put(url, componentTest)
.then(dispatch({ type: ADD_COMPONENT, payload: componentTest }))
.catch((err) => {
console.log("Add failed", err);
});
};
When I log componentTest, it get the strucutre that I want, which mean :
{
description: "je décris",
environnement: "j'environne",
name: "test",
type: "Données"
}
But on the backside, in my route when I log req.body, there is only type and name which are present. Like if the defineProperty function doesn't records my object...
I presume that i need to enumerate all the properties of my object, but my knowledges stop here
I founded it,
If someone else need it.
With defineProperty you need to configure your new object by adding :
var componentTest = inputFields.map((inputField) => {
return Object.defineProperty(componentBody, inputField.property, {
value: inputField.content,
writable: true,
enumerable: true,
configurable: true,
});
});
Now i can see my object fully.

How to access array elements that are defined in another array of Mongoose scheme object Array?

This is the User schema in mongoose:
var userSchema = new mongoose.Schema({
email: {
type: String,
unique: true,
required: true,
},
name: {
type: String,
required: true,
},
Addtasks: [
{
topic: String,
words: Number,
keywords: String,
website: String,
otherdetails: String,
exampleRadios: String,
deadline: Date,
Date: String,
fileName: String,
Bigpaths: [],
},
],
});
module.exports = mongoose.model('User', userSchema);
I want to use/access the Bigpaths array, which is defined inside the Addtasks array, which is defined in User. Data is already are there in mongoDB, which I have inserted via UI page. I am trying the following code but I am getting this error in console:
data.Addtasks[Object.keys(data.Addtasks).length - 2].Bigpaths.forEach(
(element) => {
// ...
}
)
as
TypeError: Cannot read property 'Bigpaths' of undefined
at \Desktop\grumpytext\routes\index.js:99:71
Code:
const { files } = req;
User.findOne({ email: req.user.email }, function (error, data) {
if (error) {
console.log('Three');
} else if (data) {
if (Object.keys(data.Addtasks).length > 1) {
data.Addtasks[Object.keys(data.Addtasks).length - 2].Bigpaths.forEach(
(element) => {
files.forEach((currentElement) => {
if (element.name == currentElement.filename) {
files.pull(currentElement.filename);
}
});
}
);
}
}
});
How to resolve this error or how to access all the elements of Bigpaths array so that I can iterate it with forEach loop?
I'm not sure here, but I think you need to populate Addtasks prior to manipulating it:
const files = req.files;
User.findOne({email:req.user.email}).populate('Addtasks').exec((error, data) => {
if (error) {
console.log("Three");
}
else
{
if(data)
{
if(Object.keys(data.Addtasks).length > 1)
{
console.log("Addtasks count: " + Object.keys(data.Addtasks).length);
data.Addtasks[Object.keys(data.Addtasks).length - 2].Bigpaths.forEach(element => {
files.forEach(currentElement => {
if(element.name == currentElement.filename)
{
files.pull(currentElement.filename);
}
})
});
}
}
}
});
Please notice the log console.log("Addtasks count: " + Object.keys(data.Addtasks).length); - in case the solution does not work, I advise to add some prints, especially to check if the count of elements is as expected or properties within an object are fine.

Mongoose Schema method: Error - model method is not a function

I have two Mongoose model schemas as follows. The LabReport model contains an array of the referenced SoilLab model. There is a static method in the SoilLab model that I was using to select which fields to display when LabReport is retrieved.
//LabReport.js
var mongoose = require("mongoose");
var SoilLab = mongoose.model("SoilLab");
var LabReportSchema = new mongoose.Schema(
{
labFarm: { type: mongoose.Schema.Types.ObjectId, ref: "Farm" },
testName: { type: String },
soilLabs: [{ type: mongoose.Schema.Types.ObjectId, ref: "SoilLab" }],
},
{ timestamps: true, usePushEach: true }
);
LabReportSchema.methods.toLabToJSON = function () {
return {
labReport_id: this._id,
testName: this.testName,
soilLabs: this.soilLabs.SoilToLabJSON(),
};
};
mongoose.model("LabReport", LabReportSchema);
//SoilLab.js
var mongoose = require("mongoose");
var SoilLabSchema = new mongoose.Schema(
{
description: { type: String },
sampleDate: { type: Date },
source: { type: String },
},
{ timestamps: true, usePushEach: true }
);
SoilLabSchema.methods.SoilToLabJSON = function () {
return {
description: this.description,
sampleDate: this.sampleDate,
source: this.source,
};
};
mongoose.model("SoilLab", SoilLabSchema);
When I try to retrieve the LabReport, I get "this.soilLabs.SoilToLabJSON is not a function". This is how I'm trying to retrieve LabReport.
//labReports.js
...
return Promise.all([
LabReport.find()
.populate("soilLabs")
.exec(),
LabReport.count(query).exec(),
req.payload ? User.findById(req.payload.id) : null,
]).then(function (results) {
var labReports = results[0];
var labReportsCount = results[1];
var user = results[2];
return res.json({
labReports: labReports.map(function (labReport) {
return labReport.toLabToJSON(user); //This cant find SoilToLabJSON
}),
If I remove the .SoilToLabJSON in LabReport.js and just call this.soilLabs, it works but outputs all of the soilLabs data which will become an issue when I have the model completed with more data. I have dug into statics vs methods a little and tried changing it to statics but it didn't work.
I get the soilLabs to populate but not sure why the .SoilToLabJSON method is inaccessible at this point. Do I need to find() or populate the soilLab differently? Is the method incorrect?
labReport.toLabToJSON is passing an array and that was causing the error for me. I simply edited the LabReport.js to the following to take the array and map it to SoilToLabJSON properly.
myTestSoilLabOutput = function (soilLabs) {
var test = soilLabs.map(function (soilLab) {
return soilLab.SoilToLabJSON();
});
return test;
Changed the LabReportSchema.methods.toLabToJSON to:
LabReportSchema.methods.toLabToJSON = function () {
return {
labReport_id: this._id,
testName: this.testName,
soilLabs: myTestSoilLabOutput(this.soilLabs),
};
};

Script create duplicate convensations Mongodb

I'm currently developing a conversation system with messages.
It checks if it has an active conversation ( hasConversation function) , and then determines what it should do.
If it has a conversation, then it shall only send a message, else create a conversation and then send message.
Anyway, it seems like something is wrong with my hasConversation function.
No matter what I do, it always creates two conversations, even if one exists.
It might also act like, if I call the function three times, it might create one,
then create another one, but then send the 3rd call message within the 2nd conversation.
What is wrong with my function?
It should check if both users are in a conversation.
function:
function hasConversation(userid,user2) {
return new Promise(function(resolve, reject) {
var x = [userid,user2];
var y = [user2, userid];
conversations.findOne( { members: {$all: x} }).then(function (conversation) {
// conversations.findOne({ members: x }).then(function (conversation) {
return resolve(conversation);
});
});
}
model:
var conversationsSchema = new Schema({
initiateduser : String,
name: {type:String, default: 'no name'},
members: { type: [String], default: []},
time: Number,
global: { type: Boolean, default: false},
gang: { type: Boolean, default: false},
});
a conversation is created by the following:
function createConversation(userid,user2,message) {
return new Promise(function(resolve, reject) {
var conv = new convensations();
conv.members = [userid, user2];
conv.initiateduser = userid;
conv.save(function (err,room) {
if (room._id) {
console.log("conv created, sending message");
createMessage(userid, room._id, message);
return resolve(room._id);
} else {
console.log(err);
return resolve(err);
}
});
});
}
example of calls:
Messages_model.sendNPCmessage('59312d2b329b7535b07e273c','testing','testshit?');
Messages_model.sendNPCmessage('59312d2b329b7535b07e273c','testing','testshit2?');
Messages_model.sendNPCmessage('59312d2b329b7535b07e273c','testing','testshit2?');
current output:
EDIT 1:
here is the main function calling it:
function sendNPCmessage(userid,from,message) {
console.log("checking npc conv");
return hasConversation(userid,from).then(function (haveconv) {
console.log("having conv? " + from);
console.log(haveconv);
if (haveconv) {
console.log("yes?");
return createMessage(from,haveconv._id,message).then(function (result) {
console.log("created mess?");
return result;
});
} else {
console.log("no?");
return createConversation(from,userid,message).then(function (result) {
console.log("created conv?");
return result;
});
}
});
}

Field args rejected when return a function not object

I want ask about GraphQL
This code will be failed, and shows error
Error: Mutation.addUser args must be an object with argument names as keys.
here is the code
const Schema = new GraphQLObjectType({
name: "Mutation",
description: "Mutation schema",
fields() {
return {
// Add user
addUser: {
type: UserSchema,
args: () => {
return {
firstName: {
type: GraphQLString
}
};
},
resolve(_, args){
return Db.models.user.update( () => {
return _.mapValues(args, (v, k) => {
return args[k];
});
}, {
returning: true
});
}
}
};
}
});
But, this code work perfectly
const Schema = new GraphQLObjectType({
name: "Mutation",
description: "Mutation schema",
fields() {
return {
// Add user
addUser: {
type: UserSchema,
args: {
firstName: {
type: GraphQLString
},
lastName: {
type: GraphQLString
}
},
resolve(_, args){
return Db.models.user.update( () => {
return _.mapValues(args, (v, k) => {
return args[k];
});
}, {
returning: true
});
}
}
};
}
});
Why args can't return object from function?
The fields itself can be a function, so having another function inside it to define args is kind of redundant.
The purpose of having them as functions is to be able to define types that need to refer to each other, or types that need to refer to themselves in a field.
So having only fields as a function will do the trick.

Categories

Resources