I have a model:
const wordSchema = mongoose.Schema({
author: {type: Object, default: 'unknown'},
quote: String,
source: {type: String, default: 'unknown', index: true},
rating: {type: Number, default: 0},
createdAt: {type: Date, default: Date.now},
updatedAt: {type: Date, default: Date.now},
});
Now after receiving a POST request to my server, I want to make a GET request to wikipedia, and get the author info, then append it to my model as an object, and write this model into my database.
app.post('/', function(req, res) {
let author = {};
let quote = new Word({
author: req.body.author,
quote: req.body.quote,
source: req.body.source,
rating: req.body.rating,
});
let authorName = req.body.author.replace(/ /g, '%20');
let url = 'https://en.wikipedia.org/w/api.php?action=query&format=json&titles=' + authorName + '&prop=pageimages|extracts&pithumbsize=200&exsentences=10&exintro=true';
request.get(url, (error, response, body) => {
if(error) {
return error;
}
let data = JSON.parse(body);
let pageID;
for(page in data.query.pages) {
pageID = page;
}
author = {
name: req.body.author,
thumbnail: data.query.pages[pageID].thumbnail.source,
flavorText: data.query.pages[pageID].extract,
};
});
// Save the quote
quote.pre('save', (next) => {
this.author = author;
})
quote.save(function(err, quote) {
if (err) {
res.send(err);
}
res.redirect('/words');
});
});
Now I tried updating the value with the .pre function, but I am getting
quote.pre is not a function
What would be the 'correct way of doing this and what am I doing wrong?
quote is not a Mongoose schema, but wordSchema is so it needs to be as follow:
wordSchema.pre('save', (next) => {
this.quote = whteverYouWantToAssignWith;
})
But actually you don't need it in your use case as far as I understand, you may achieve what you want as follow:
app.post('/', function(req, res) {
let authorName = req.body.author.replace(/ /g, '%20');
let url = 'https://en.wikipedia.org/w/api.php?action=query&format=json&titles=' + authorName + '&prop=pageimages|extracts&pithumbsize=200&exsentences=10&exintro=true';
request.get(url, (error, response, body) => {
if(error) {
return error;
}
let data = JSON.parse(body);
let pageID;
for(page in data.query.pages) {
pageID = page;
}
let quote = new Word({
author: {
name: req.body.author,
thumbnail: data.query.pages[pageID].thumbnail.source,
flavorText: data.query.pages[pageID].extract,
},
quote: req.body.quote,
source: req.body.source,
rating: req.body.rating,
});
quote.save(function(err, quote) {
if (err) {
res.send(err);
}
res.redirect('/words');
});
});
});
Related
I have Schema With name score, and that have an iduser: req.session.user._id.
and I have more than one items with same iduser. I wanna to find all the items with the same iduser. and I use the
var users = await storescors16.find({ id }) id = res.session.user._id.
but that show me all the items in score !
My code
//schema
const storescor = new mongoose.Schema({
iduser: String,
level: { type: String, default: null },
day: { type: String, default: null },
date: { type: String, default: null },
time: { type: String, default: null },
objectif: { type: String, default: null }
})
var storescors16 = mongoose.model("storescor", storescor);
//post infos to database
router.post('/control/edite-control', (req, res) => {
console.log(req.session.selectuserid);
var { level, day, date, time, ob } = req.body
var scor = new storescors16({
iduser: req.session.selectuserid,
level: level,
day: day,
date: date,
time: time,
objectif: ob,
})
//read infos from databse
router.get('/result', auth, async(req, res) => {
var id = req.session.user._id
console.log(id);
var user = User.findById(id, (err, docs) => {
if (err)
console.log(err);
else
console.log();
})
var ids = req.session.user._id
var notes = await storescors16.find({ ids })
console.log(notes);
let scor = user.quiz
res.render('./options/result', {
notes: notes,
scor: scor,
title: 'سجل درجات النجم',
name: session.user.name,
email: session.user.email,
})
});
I use nodejs as backend
If you want to find all use findAll function with where.
const users = await storescors16.findAll({ id });
That if I understand you currect.
I have 2 collections called User and Location. In User, there is a location _id and this is an Object. Id also references the location collection. My question is what did I do wrong? When I call getUser function I want to see user information and the user's location information. What I need to do ?
User Schema
module.exports = (function userSchema() {
var Mongoose = require('mongoose');
var userSchema = Mongoose.Schema({
name: {
type: String,
require: true
},
surname: {
type: String,
require: true
},
tel: {
type: String,
require: true
},
age: {
type: String,
require: true
},
mevki_id: {
type: String,
require: true
},
location_id: [{
type: Mongoose.Schema.Types.ObjectId,
ref: 'locations'
}]
});
var collectionName = 'users';
var User = Mongoose.model(collectionName, userSchema);
return User;
})();
User Controller
function userController() {
var User = require('../models/UserSchema');
this.createUser = function (req, res, next) {
var name = req.body.name;
var surname = req.body.surname;
var tel = req.body.tel;
var age = req.body.age;
var mevki_id = req.body.mevki_id;
var lok_id = req.body.lok_id;
User.create({
name: name,
surname: surname,
tel: tel,
age: age,
mevki_id: mevki_id,
lok_id: lok_id
}, function (err, result) {
if (err) {
console.log(err);
return res.send({
'error': err
});
} else {
return res.send({
'result': result,
'status': 'successfully saved'
});
}
});
};
this.getUser = function (req, res, next) {
User.find()
.populate('lok_id')
.exec(function (err, result) {
if (err) {
console.log(err);
return res.send({
'error': err
});
} else {
return res.send({
'USERS': result
});
}
});
};
return this;
};
module.exports = new UserController();
First, your schema is wrong:
var userSchema = new Mongoose.Schema({
// ...
location_id: { type: [Mongoose.Schema.Types.ObjectId], ref: 'locations' }
})
Second, in your schema the last field name is location_id while in your controller, you change it to lok_id.
So, fix this:
User.create({
// ...
location_id: lok_id
}
and this:
User
.find()
.populate('location_id')
UPDATE
In your json the last field name is location_id, therefore, fix this too:
this.createUser = function (req, res, next) {
// ...
var lok_id = req.body.location_id;
}
I have the following combination, NodeJS, Express, MongoDB, and Mongoose. I have implemented a nonce with mongoose promises to allow for concurrent edits. See the following.:
//schema
var item_schema = {
//_id: {type: Schema.ObjectId, required: true},
name: {type: String, required: true, index: { unique: true }},
code: {type: String, required: true, index: { unique: true }},
date_time_created: {type: Date, required: true},
date_time_updated: {type: Date, required: true},
nonce: {type: Schema.ObjectId}
};
//model
var item_model = mongoose.model('item', schema);
//update
var concurrency_update = function(req, res, retries) {
var promise = model.findById(req.params.id).exec();
var updated_nonce = mongoose.Types.ObjectId();
promise.then(function(document){ //find document response
if(!document) {
res.status = 404;
return Promise.reject( { "message" : req.params.id + ' document does not exist' } );
}
var now = new Date();
if(req.body.code) {
document.code = req.body.code;
document.date_time_updated = now;
}
if(req.body.name) {
document.name = req.body.name;
document.date_time_updated = now;
}
if(!document.nonce) {
document.nonce = updated_nonce;
var old_nonce = document.nonce;
}
else {
var old_nonce = document.nonce;
document.nonce = updated_nonce;
}
return document.update({ "_id" : req.params.id, "nonce" : old_nonce }).exec();
}).then(function(raw){ //update response
var number_affected = raw.n;
console.log(raw);
if(!number_affected && retries < 10){
//we weren't able to update the doc because someone else modified it first, retry
console.log("Unable to update, retrying ", retries);
//retry with a little delay
setTimeout(function(){
concurrency_update(req, res, (retries + 1));
}, 20);
} else if (retries >= 10){
//there is probably something wrong, just return an error
return Promise.reject({ "message" : "Couldn't update document after 10 retries in update"});
} else {
res.json({"message": req.params.id + ' document was update'});
}
}).catch(function(err){
res.send(err.message);
});
The concurrency update is based of of this:
http://www.mattpalmerlee.com/2014/03/22/a-pattern-for-handling-concurrent/
and reading the mongoose docs the update is based off of this.
http://mongoosejs.com/docs/api.html#document_Document-update
However, when the code enters the final .then (//update response) I see the raw.n (numberAffected) = 1 but the database never gets updated?
The answers probably close but I am missing it.
What am I missing on this?
After the comment by #blakes_seven, I was able to remove the use of nonce and apply updates using atomic modifiers. Here is the updated tested code.
//schema
var item_schema = {
//_id: {type: Schema.ObjectId, required: true},
name: {type: String, required: true, index: { unique: true }},
code: {type: String, required: true, index: { unique: true }},
date_time_created: {type: Date, required: true},
date_time_updated: {type: Date, required: true},
nonce: {type: Schema.ObjectId}
};
//model
var item_model = mongoose.model('item', schema);
//update
var concurrency_update = function(req, res, retries) {
var updated_data = {};
if(req.body.code) {
updated_data.code = req.body.code;
}
if(req.body.name) {
updated_data.name = req.body.name;
}
if(!req.body.name.nonce) {
updated_data.nonce = mongoose.Types.ObjectId();
}
if(updated_data !== {}) {
var update = {
$currentDate: {
date_time_updated: true
},
$set: updated_data
};
var promise = model.update({"_id": req.params.id}, update).exec();
promise.then(function (raw) {
var number_affected = raw.nModified;
console.log(raw);
if (!number_affected && retries < 10) {
//we weren't able to update the doc because someone else modified it first, retry
console.log("Unable to update, retrying ", retries);
//retry with a little delay
setTimeout(function () {
concurrency_update(req, res, (retries + 1));
}, 20);
} else if (retries >= 10) {
//there is probably something wrong, just return an error
return Promise.reject({"message": "Couldn't update document after 10 retries in update"});
} else {
res.json({"message": req.params.id + ' document was update'});
}
}).catch(function (err) {
res.send(err.message);
});
}
else {
res.status = 400;
res.send({"message": 'There is nothing specified in the payload to update!'})
}
};
I'm working with node.js, expressjs 4, and mongoose.
My mongoose shema is that:
var MachineSchema = new mongoose.Schema({
serial_num: { type: String},
description: {type: String},
nature: {type: String, sparse: true},
mark: {type: String },
type: String,
history: {
date: Date,
action: String,
description: String,
specif_infos: {
client: String,
number: Number
}
},
purchase_date: {type: Date},
actual_owner: {
first_name: {type: String},
last_name: {type: String},
phone: {type: Number},
owner_address:
{
avenue: {type: String},
city: {type: String},
country: {type: String},
postal_code: { type: Number}
}
},
actual_concess: {
name: String,
phone: Number,
concess_address:
{
avenue: String,
city: String,
country: String,
postal_code: { type: Number, min: 0, max: 99999}
}
}
});
how can i post some data?
i tried to use raw in POSTMAN but is doesn't work!
any idea please?
and for my controller: machine.js
exports.postMachines = function (req, res) {
var machine = new Machine();
machine.serial_num = req.body.serial_num;
machine.description = req.body.description;
machine.nature = req.body.nature;
machine.mark = req.body.mark;
machine.type = req.body.type;
machine.history = req.body.history;
machine.purchase_date = req.body.purchase_date;
machine.actual_owner = req.body.actual_owner;
machine.actual_concess = req.body.actual_concess;
machine.save(function (err) {
if (err) {
res.json({ message: 'la machine ne peut pas être ajoutée'});*/
res.send(err);
} else {
res.json({ message: 'machine ajoutée', data: machine});
}
});
};
exports.getMachines = function (req, res) {
Machine.find(function (err, machines) {
if (err) {
res.send(err);
}
res.json(machines);
});
};
exports.getMachine = function (req, res) {
Machine.findById(req.params.id, function (err, machine) {
if (err) {
res.send(err);
}
res.json(machine);
});
};
exports.getMachine = function (req, res) {
Machine.findOne(req.params.mark, function (err, machine) {
if (err) {
res.send(err);
}
res.json(machine);
});
};
exports.putMachine = function (req, res) {
Machine.findById(req.params.id, function (err, machine) {
if (err) {
res.send(err);
}
machine.history = [req.body.history];
machine.actual_owner = req.body.actual_owner;
machine.actual_concess = [req.body.actual_concess];
return machine.save(function (err) {
if (!err) {
console.log("machine mise à jour");
} else {
console.log("erreur : " + err);
}
return res.json(machine);
});
});
};
exports.deleteMachine = function (req, res) {
Machine.findByIdAndRemove(req.params.id, function (err) {
if (err) {
res.send(err);
}
res.json({ message: 'machine supprimée!' });
});
};
exports.deleteMachines = function (req, res) {
Machine.remove(function (err, machines) {
if (err) {
res.send(err);
}
res.json("machines supprimées");
});
};
You must do the mapping between your functions and the HTTP method, for example:
var express = require('express');
var app = express();
app.get('/', function(req, res){
res.send('hello world');
});
In your case, you shold pass the app object to your router file and do something like:
module.exports = function(app) {
postMachines = function (req, res) {
var machine = new Machine();
machine.serial_num = req.body.serial_num;
machine.description = req.body.description;
machine.nature = req.body.nature;
machine.mark = req.body.mark;
machine.type = req.body.type;
machine.history = req.body.history;
machine.purchase_date = req.body.purchase_date;
machine.actual_owner = req.body.actual_owner;
machine.actual_concess = req.body.actual_concess;
machine.save(function (err) {
if (err) {
res.json({ message: 'la machine ne peut pas être ajoutée'});*/
res.send(err);
} else {
res.json({ message: 'machine ajoutée', data: machine});
}
});
}
app.get('/machines', getMachines);
app.post('/machines', postMachines);
app.delete('/machines/:id', deleteMachines);
}
Can you tell me what i'm doing wrong ?
var ObjectId = Schema.Types.ObjectId;
var ProductSchema = new Schema({
name: { type: String, required: true },
price: { type: Number, required: true },
category : { type: String, required: true }
});
var OrderSchema = new Schema({
products: [{
product: {type: ObjectId, ref: 'Product'},
quantity: {type: Number}
}],
status: { type: String, required: true }
});
Product = mongoose.model('Product', ProductSchema);
Order = rmongoose.model('Order', OrderSchema);
OrderSchema.statics.addOrder = function (data, cb) {
// data: array of products ID
var newOrder = new Order();
data.data.forEach(function(element, index, array) {
Product.findOne({ '_id': element.id }, function (err, product) {
if (err) return handleError(err);
newOrder.products.push({product: product, quantity: element.quantity});
})
});
newOrder.status = 'waiting';
newOrder.save(function (err, order) {
if (err) cb(err, false);
console.log(order);
var response = json.stringify({
event: 'addOrder',
success: true,
data: order.id
});
cb(false, response);
});
}
When i add an order products, array is always empty but i have no error. Maybe it's the wrong to do what i want.
Data send by the client are good and the foreach and findOne work well but push seems doing nothing.
If there is no solution maybe you can try to help me to find another solution.
Thanks :)
That's because you need to wait for all the products to be found.
Try this (untested):
OrderSchema.statics.addOrder = function (data, cb) {
// data: array of products ID
var newOrder = new Order();
var productIds = [];
var quantity = [];
data.data.forEach(function(element, index, array) {
productIds.push(element.id);
quantity.push(element.quantity);
});
Product.find({ '_id' : { $in: productIds} }, function(err, products) {
if (err) return handleError(err);
products.forEach(function(product, index) {
newOrder.products.push({product: product, quantity: quantity[index]});
});
newOrder.status = 'waiting';
newOrder.save(function (err, order) {
if (err) cb(err, false);
console.log(order);
var response = json.stringify({
event: 'addOrder',
success: true,
data: order.id
});
cb(false, response);
});
});
});