In my project I have 2 models: Store and product, basically every store can have a number of products, but each product can be related to 1 store, so to build the models I did this:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var lojasSchema = new mongoose.Schema({
email: {
type: String,
unique: true,
required: true
},
nome: {
type: String,
required: true,
unique: true
},
descricao: {
type: String,
default: "No description for this store"
},
telefone:{
type:String,
},
password:
{
type: String, required: true
}
,
img: {
data: Buffer, contentType: String
},
imgNome: {
type: String
},
produtos: [
{ type: mongoose.Schema.ObjectId, ref: 'Produto' }
],
});
module.exports = mongoose.model('Loja', lojasSchema);
my product is like this
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var produtoSchema = mongoose.Schema({
nome:{
type:String, required:true
},
stock:{
type:Number
},
descricao:{
type:String
},
categoria:{
type: String, required:true
},
tamanho:{
type: String, required:true
},
data:{
type: Date, default: Date.now
},
preco:{
type: Number,required:true, default: 0
}
});
module.exports = mongoose.model('Produto',produtoSchema);
as you guys can see I have the reference on the store side, basically what I want is every time I add a product I add that product directly to a store(storeID), so to do that I added this to my store side routes:
//adiciona um produto a uma loja especifica
router.post('/:id/produtos',function(req,res){
Loja.findById(req.params.id,function(err,loja){
if(!loja){
return res.status(404).json({Error:"Loja nao encontrada"});
}
if(JSON.stringify(req.body) == "{}")
{
return res.status(400).json({Error:"Your request is empty"});
}
var produto = new Produto(req.body);
loja.produtos.push(produto);
loja.save(function(err){
if(err){
return res.status(500).json({Error:"Server problem"});
}
res.status(200).json({message: "product added"});
});
})
})
I got 2 problems: when I go to my get products route, I get an empty array, I should get there all the products, I think the product is not getting added in the product's model, the second problem is: every time I add a product to my store, and go to see all my stores with the .populate I just can see an id inside the products array, I should see all the product details, what am I doing wrong?:S
Update you mongoose to 4.8.1 because 4.7.6 is buggy with casting Ids.
then go to your lojas.js and require mongoose at the top.
Replace your code with this
router.post('/:id/produtos',function(req,res){
var queryObject = {_id : mongoose.Types.ObjectId(req.params.id)};
Loja.findById(queryObject,function(err,loja){
console.log(err);
if(!loja){
return res.status(404).json({Error:"Loja nao encontrada"});
}
if(JSON.stringify(req.body) == "{}")
{
return res.status(400).json({Error:"Your request is empty"});
}
var produto = new Produto(req.body);
produto.save(function (err) {
if(err){
return res.status(500).json({Error:"Server Problem"})
}
loja.produtos.push(produto._id);
loja.save(function(err){
if(err){
return res.status(500).json({Error:"Server problem"});
}
res.status(200).json({message: "product added"});
});
});
})
})
Related
I'm trying to retrieve a value with my schemas directed at another collection in the db:
_id: 61b248b0cd79df2124dcf283
name: "david"
email: "email#gmail.com"
dogRaces: 61a22138fdb728445ef9a067 (points to oid in another collection: {name: "name"})
expert: 61a2255b0f5aeabad0e3785b (points to oid in another collection: {name: "name"})
location: 61b248b0cd79df2124dcf282 (points to oid in another collection: {name: "name"})
In the frontend when I retrieve the information, the values are presented as the oid's and not the names inside the documents.
how can I retrieve my information correctly using nodejs?
here is my mongoose schema:
const mongoose = require('mongoose')
const trainerSchema = new mongoose.Schema({
name: {
type:String,
required: true,
},
email: {
type:String,
required:true,
},
registrationDate: {
type:Date,
default: Date.now,
},
dogRaces: {
type:mongoose.Types.ObjectId, ref:"DogRace"
},
expert: {
type:mongoose.Types.ObjectId, ref:"Expert"
},
location: {
type:mongoose.Types.ObjectId, ref:"City"
},
})
module.exports = mongoose.model('Trainer', trainerSchema);
my njs code:
async function getTrainer(req,res,next) {
let trainer
try {
trainer = await Trainer.findById(req.params.id)
.populate('dogRaces')
.populate('expert')
.populate('location');
if (trainer == null) {
return res.status(404).json({message: 'Cannot find trainer'});
}
}
catch(err) {
return res.status(500).json({message: err.message});
}
Thanks!
Using mongoose this is pretty straightforward through .populate(). So in your case, it'd look something like:
const trainer = await Trainer.findOne({...})
.populate('dogRaces')
.populate('expert')
.populate('location');
Edit trainerSchema like :
const mongoose = require('mongoose')
const DogRace = require('../yourentitypath/DogRace')
const Expert = require('../yourentitypath/Expert')
const City = require('../yourentitypath/City')
const trainerSchema = new mongoose.Schema({
name: {
type:String,
required: true,
},
email: {
type:String,
required:true,
},
registrationDate: {
type:Date,
default: Date.now,
},
dogRaces: {
type:mongoose.Schema.Types.ObjectId, ref:"DogRace"
},
expert: {
type:mongoose.Schema.Types.ObjectId, ref:"Expert"
},
location: {
type:mongoose.Schema.Types.ObjectId, ref:"City"
},
})
module.exports = mongoose.model('Trainer', trainerSchema);
i have 2 schemas
const schema = mongoose.Schema(
{
id_film: {
type: Number,
unique: true,
require: true,
trim: true,
},
recommendation: [{
type: Number,
ref: 'Films'
}]
}, { timestamps: true }, { _id: false }
);
export const Recommendation = mongoose.model("Recommendations", schema);
const schema = mongoose.Schema(
{
name:{
type: String,
}
id: {
type: Number,
ref: 'Recommendations'
},
}
export const Films = mongoose.model("Films", schema);
the recommendation contains a list id of model Films, and I want to show all id film
i try it
Recommendation.findOne({ id_film: req.params.id }).populate('recommendation').exec(function (err, film) {
if (err) return handleError(err);
res.json(film);
});
but it's not working, it just shows the list id not id and name
In this application, I am trying to update a field value, if it is successful then I want to save into a log collection, however, not all the data are saved in the log collection, I am not sure if I am doing it the right way, would appreciate if someone could help out.
here is the query :
// both models(Log & Inventory are imported)
router.get("/add_product/:id/:num/:quantity/:order", (req, res) => {
var id = req.params.id;
var quantity = req.params.quantity;
var order = req.params.order;
// console.log('id----', id);
var num_mod = req.params.num;
var modified_count = parseInt(num_mod) - parseInt(quantity);
console.log("num_mod----", num_mod);
Inventory.findByIdAndUpdate(id, { quantity: parseInt(num_mod) }, { new: true }, function(
err,
inventory
) {
if (err) {
console.log("err", err);
res.status(500).send(err);
} else {
console.log(inventory.name);
const newLog = new Log({
name: inventory.name,
description: inventory.description,
price: parseInt(inventory.price),
quantity: parseInt(inventory.quantity),
modified_quantity: parseInt(modified_count),
itemDest: order //this is not being saved
});
newLog.save(function(err, Log) {
if (err) {
console.log(err);
} else {
console.log("add log success");
res.send(inventory);
}
});
}
});
});
URL from front end :
// order is a string
here is the Log schema :
const mongoose = require("mongoose");
const LogSchema = new mongoose.Schema(
{
// _id: mongoose.Schema.Types.ObjectId,
name: { type: String, required: true },
description: { type: String, required: true },
price: { type: Number, required: true },
quantity: { type: Number, required: true },
modified_quantity: { type: Number, required: true },
supplier: String,
taxable: Boolean,
itemDest: String
},
{ timestamps: true }
);
// Create model from the schema
const Log = mongoose.model("Log", LogSchema);
// Export model
module.exports = Log;
and here is the inventory schema
const mongoose = require("mongoose");
//create Schema
const InventorySchema = new mongoose.Schema(
{
// _id: mongoose.Schema.Types.ObjectId,
name: { type: String, required: true },
description: { type: String, required: true },
price: { type: Number, required: true },
quantity: { type: Number, required: true },
supplier: String,
taxable: Boolean
},
{ timestamps: true }
);
// Create model from the schema
const Inventory = mongoose.model("Inventory", InventorySchema);
// Export model
module.exports = Inventory;
My issue is with this line "itemDest: order" in the query, I intend to save the value of "order" extracted from "req.params.order" into "itemDest" but it doesn't save.
I am not a totally new populate user but now I do not know what's wrong.
Here I need to populate my designerId which is type of ObjectId. Take a look at my route.
ordersAdminRouter.route('/customorder/add')
.post(function(req, res){
body = req.body;
console.log(body);
CustomOrders.create(body, function(err, saved){
if (err) throw err;
Designs.findByIdAndUpdate(saved.designId, {$set: {status: 'Order Sent'}}, {new: true}).exec()
.then(function(updated){
return CustomOrders.findById(saved._id).populate(saved.designId).exec();
})
.then(function(orders){
res.json(orders);
})
.then(undefined, function(err){
console.log(err);
})
});
});
saved._id is working because when I remove the populate, it returns the document that I need without the populated document of course.
Take a look at my schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var customOrderSchema = new Schema({
designId: { type: Schema.Types.ObjectId, ref: 'customDesigns' },
size: { type: String },
quantity: { type: Number },
totalPrice: { type: Number },
paymentMode: { type: String },
rcpt_img: { type: String },
refNumber: { type: String }
});
module.exports = mongoose.model('customOrders', customOrderSchema);
Here is my customDesigns schema.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var customDesignSchema = new Schema({
item_name: { type: String },
price: { type: Number, default: 0 },
img_url_front: { type: String },
img_url_back: { type: String },
designer: { type: Schema.Types.ObjectId, ref: 'users' },
color: { type: String },
designDate: { type: Date, default: Date.now() },
status: { type: String, default: 'For Qoutation' }
});
module.exports = mongoose.model('customDesigns', customDesignSchema);
I need to admit that I am new to promises on mongoose & express and this is my first time doing so. But using populate, i use it more than I can think of. Any suggestions?
return CustomOrders.findById(saved._id).populate('designId').then(.. your code);
By the way, you dont must use .exec() then you want execute your query, .then executes query as well. You can skip .exec()
http://mongoosejs.com/docs/populate.html
http://mongoosejs.com/docs/api.html#query_Query-populate
I have a model called Shop whos schema looks like this:
'use strict';
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var ShopSchema = new Schema({
name: { type: String, required: true },
address: { type: String, required: true },
description: String,
stock: { type: Number, default: 100 },
latitude: { type: Number, required: true },
longitude: { type: Number, required: true },
image: String,
link: String,
tags: [{ type: Schema.ObjectId, ref: 'Tag' }],
createdAt: { type: Date, default: Date.now },
updatedAt: { type: Date, default: Date.now }
});
module.exports = mongoose.model('Shop', ShopSchema);
I want to use the array tags to reference to another model via ObjectId obviously. This set up works fine when I add ids into the property via db.shops.update({...}, {$set: {tags: ...}}) and the ids get set properly. But when I try to do it via the Express.js controller assigned to the model, nothing gets updated and there even is no error message. Here is update function in the controller:
// Updates an existing shop in the DB.
exports.update = function(req, res) {
if(req.body._id) { delete req.body._id; }
Shop.findById(req.params.id, function (err, shop) {
if (err) { return handleError(res, err); }
if(!shop) { return res.send(404); }
var updated = _.merge(shop, req.body);
shop.updatedAt = new Date();
updated.save(function (err) {
if (err) { return handleError(res, err); }
return res.json(200, shop);
});
});
};
This works perfect for any other properties of the Shop model but just not for the tags. I also tried to set the type of the tags to string, but that didn't help.
I guess I am missing something about saving arrays in Mongoose?
It looks like the issue is _.merge() cannot handle merging arrays properly, which is the tags array in your case. A workaround would be adding explicit assignment of tags array after the merge, if it is ok to overwrite the existing tags.
var updated = _.merge(shop, req.body);
if (req.body.tags) {
updated.tags = req.body.tags;
}
Hope this helps.. If the workaround is not sufficient you may visit lodash forums.