product is not added to my collection - node.js

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

Mongoose Schemas Object ID Type Value return?

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);

populate an array in mongodb

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

How to use mongoose to make changes in two different collections in one nodejs query

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.

Mongoose: utils.populate: invalid path. Expected string. Got typeof 'undefined'

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

Save array of ObjectId in Schema

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.

Resources