Angular is not sending objects in objects - angularjs

I'm sending this JSON with Angular.js to my node.js/express.js service:
{
"name": "MyGuitar",
"type": "electric",
"userid": "123",
"likes": 0,
"dislike": 0,
"guitarParts": {
"body": {
"material": "/content/img/hout.jpg",
"_id": "5566d6af274e63cf4f790858",
"color": "#921d1d"
},
"head": {
},
"neck": {
"material": "/content/img/hout.jpg",
"_id": "556d9beed90b983527c684be",
"color": "#46921d"
},
"frets": {
},
"pickup": {
},
"bridge": {
},
"buttons": {
}
}
}
The guitarParts are not saved in the MongoDB database.
Mongoose inserts the following:
Mongoose: guitars.insert({ name: 'MyGuitar', type: 'electric', userid: '123', likes: 0, _id: ObjectId("557023af9b321b541d4d416e"), guitarParts: [], __v: 0})
This is my Mongoose model:
guitarPart = new Schema({
id: { type: String, required: true },
color: { type: String, required: true },
material: { type: String, required: true },
x: { type: Number, required: false },
y: { type: Number, required: false },
width: { type: Number, required: false },
height: { type: Number, required: false},
});
guitarParts = new Schema({
body: [guitarPart],
neck: [guitarPart],
head: [guitarPart],
bridge: [guitarPart],
frets: [guitarPart],
pickup: [guitarPart],
buttons: [guitarPart]
});
guitar = new Schema({
name: { type: String, required: true, unique: false },
type: { type: String, required: true },
userid: { type: String },
likes: { type: Number },
dislikes: { type: Number },
guitarParts: [guitarParts],
kidsguitar: { type: Boolean },
lefthanded: { type: Boolean },
assemblykit: { type: Boolean }
},
{
collection: 'guitars'
});
I don't know what's going wrong. Any ideas?

According to the mongoose documentation of Subdocuments says: Sub-documents are docs with schemas of their own which are elements of a parents document array
And in your schema you provided: guitarParts is not an array, it is an object and a guitarPart is not array it is an object too. So that's why it is not saving.
So the correct way to model your Schema it would be:
var guitarDefinition = {
_id: {type: String, required: true},
color: {type: String, required: true},
material: {type: String, required: true},
x: Number,
y: Number,
width: Number,
heigth: Number
};
var guitarSchema = Schema({
name: { type: String, required: true, unique: false },
type: { type: String, required: true },
userid: String,
likes: Number,
dislikes: Number ,
kidsguitar: Boolean,
lefthanded: Boolean ,
assemblykit: Boolean,
guitarParts: {
body: guitarDefinition,
neck: guitarDefinition,
head: guitarDefinition,
bridge: guitarDefinition,
frets: guitarDefinition,
pickup: guitarDefinition,
buttons: guitarDefinition
}
});
Actually I have run in my computer and it is saving you can see my complete code here: https://gist.github.com/wilsonbalderrama/f10c38f9fb510865edc2

Related

How do I update individual fields in nested objects that are in arrays in MongoDB using Mongoose?

This is my first post so please bear with me. I am building a LinkedIn clone and I am trying to keep track of the work experience, projects and courses of the users, and those will be kept in an array of objects inside of the User schema. Now let's say a user will try to add or update one of the elements in one of those arrays, I have the user ID and I am passing it to findOneAndUpdate() as the filter.
Here is my User schema:
const userSchema = new mongoose.Schema({
user_id: {
type: String,
required: [true, 'User ID required.'],
unique: true,
immutable: true,
},
name: {
type: String,
required: [true, 'Name required.'],
},
email: {
type: String,
required: [true, 'Email required.'],
unique: true,
lowercase: true,
immutable: true,
},
title: {
type: String,
},
location: {
type: String,
},
phone_number: {
type: String,
},
contact_email: {
type: String,
},
photo: {
type: String,
},
website: {
type: String,
},
backdrop: {
type: String,
},
summary: {
type: String,
},
work: {
type: String,
},
connections: {
type: Number,
},
projects: [
{
title: {
type: String,
},
description: {
type: String,
},
start_date: {
type: Date,
},
end_date: {
type: Date,
},
technologies: {
type: String,
},
picture: {
type: String,
},
},
],
skills: [{
skill: {
name: {
type: String,
},
level: {
type: String,
},
},
}],
experience: [
{
company: {
type: String,
},
logo: {
type: String,
},
title: {
type: String,
},
location: {
type: String,
},
start_date: {
type: Date,
},
end_date: {
type: Date,
},
description: {
type: String,
},
},
],
education: [
{
school: {
type: String,
},
logo: {
type: String,
},
degree: {
type: String,
},
location: {
type: String,
},
start_date: {
type: Date,
},
end_date: {
type: Date,
},
description: {
type: String,
},
},
],
languages: [
{
name: {
type: String,
},
level: {
type: String,
},
},
],
awards: [
{
title: {
type: String,
},
date: {
type: Date,
},
awarder: {
type: String,
},
summary: {
type: String,
},
},
],
courses: [
{
title: {
type: String,
},
number: {
type: String,
},
school: {
type: String,
},
start_date: {
type: Date,
},
end_date: {
type: Date,
},
description: {
type: String,
},
},
],
});
And in my UserController.ts file, I tried using this:
const updateUser = async (req: Request, res: Response) => {
try {
const filter = { user_id: req.body.user_id };
const update = req.body;
const updatedUser = await User.findOneAndUpdate(filter, update, {
new: true,
upsert: true,
});
res.status(201).json({
status: 'success',
data: {
user: updatedUser,
},
});
} catch (err) {
res.status(400).json({
status: `ERROR: ${err}`,
message: 'error updating user',
});
}
};
And in my request using the format of the schema but that didn't work out as expected. I know mongoose will automatically give it an _id field to each of the individual objects in the array, but again, I have had no luck updating them. I tried sending a PATCH request with this as the body to add a skill like so:
{
"user_id": "xxxxxxxxxxxxxxxx",
"title": "Mr.",
"skills" : {
"name": "Flute",
"level": "Novice"
}
}
And this was the response I got. It created a skill but didnt add the data in the skill object:
{
"status": "success",
"data": {
"user": {
"_id": "63d3715f2ef9698667230a53",
"user_id": "xxxxxxxxxxxxxxxx",
"name": "Jonathan Abitbol",
"email": "yoniabitbol1#gmail.com",
"projects": [],
"skills": [
{
"_id": "63d4068d2df30c9e943e4608"
}
],
"experience": [],
"education": [],
"languages": [],
"awards": [],
"courses": [],
"__v": 0,
"title": "Mr."
}
}
}
Any help on how to add/edit the nested objects would be appreciated.

Mongoose updating subdocument array

I want to update rooms subdocument which is in Property document, but I get this error:
MongoServerError: Updating the path 'rooms.$.updatedAt' would create a
conflict at 'rooms.$'
Error which i got in postman:
{
"ok": 0,
"code": 40,
"codeName": "ConflictingUpdateOperators",
"$clusterTime": {
"clusterTime": {
"$timestamp": "7137698220989218823"
},
"signature": {
"hash": "34spx6E0zZFa5bVYFSL2JyjFszQ=",
"keyId": {
"low": 2,
"high": 1646669662,
"unsigned": false
}
}
},
"operationTime": {
"$timestamp": "7137698220989218823"
}
}
My property model:
import { IReview, ReviewSchema } from './reviews.model'
import { IRoom, RoomSchema } from './room.model'
type TCheapestRoom = {
roomType: string
bedType: string
lastPrice: number
actualPrice: number
}
export interface IProperty {
propertyType: string
name: string
description: string
city: string
photos: [string]
cheapestRoom: TCheapestRoom
adress: string
distance: number
cancellationPolicy: string
meals: string
funThingsToDo: [string]
accessibility: [string]
rooms: IRoom[]
reviews: IReview[]
}
interface IPropertyDocument extends IProperty, Document {
createdAt: Date
updatedAt: Date
// rooms: Types.Array<IRoom>
}
const PropertySchema = new Schema<IPropertyDocument>(
{
propertyType: { type: String, required: true },
name: { type: String, required: true },
description: { type: String, required: true },
city: { type: String, required: true },
photos: { type: [String] },
cheapestRoom: {
roomType: { type: String },
bedType: { type: String },
lastPrice: { type: Number },
actualPrice: { type: Number },
},
adress: { type: String, required: true },
distance: { type: Number, required: true },
cancellationPolicy: { type: String, required: true },
meals: { type: String, required: true },
funThingsToDo: { type: [String] },
accessibility: { type: [String] },
rooms: [RoomSchema],
reviews: [ReviewSchema],
},
{
timestamps: true,
}
)
const PropertyModel = model<IPropertyDocument>('Property', PropertySchema)
export default PropertyModel
Subdocument room model:
export interface IRoom {
roomType: string
bedTypes: [string]
roomFacilities: [string]
sleeps: number
lastPrice: number
actualPrice: number
cancellation: string
payment: string
breakfast: string
unavailableDates: [Date]
}
export interface IRoomDocument extends IRoom, Document {
createdAt: Date
updatedAt: Date
}
export const RoomSchema = new Schema<IRoomDocument>(
{
roomType: { type: String, required: true },
bedTypes: { type: [String], required: true },
roomFacilities: { type: [String], required: true },
sleeps: { type: Number, required: true, default: 2 },
lastPrice: { type: Number, required: true },
actualPrice: { type: Number, required: true },
cancellation: { type: String, required: true },
payment: { type: String, required: true },
breakfast: { type: String, required: true },
unavailableDates: { type: [Date] },
},
{
timestamps: true,
}
)
const RoomModel = model<IRoomDocument>('Room', RoomSchema)
export default RoomModel
room controller:
import PropertyModel from '../models/property.model'
import RoomModel from '../models/room.model'
const updateRoom = async (req: Request, res: Response) => {
try {
const updatedProperty = await PropertyModel.findOneAndUpdate(
{ _id: req.params.propertyId, 'rooms._id': req.params.roomId },
{
$set: { 'rooms.$': req.body },
},
{
new: true,
}
)
res.status(201).json(updatedProperty)
} catch (error) {
console.log(error)
res.status(400).json(error)
}
}
export { addNewRoom, deleteRoom, updateRoom }
I want to be able updating my subdocuments, in this case rooms using property id and room id.
How can i update this subdocument ?

model in mongodb user and product ref not working

my code does not working model of mongodb user and product ref does not work for me
and showing
error
Order validation failed: user: Path user is required., orderItems.0.product: Path product is required.
how can i solve it please help me
import mongoose from "mongoose";
const orderSchema = mongoose.Schema(
{
user: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "User",
},
orderItems: [
{
name: { type: String, required: true },
qty: { type: Number, required: true },
image: { type: String, required: true },
price: { type: Number, required: true },
product: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "Product",
},
},
],
shippingAddress: {
address: { type: String, required: true },
city: { type: String, required: true },
postalCode: { type: String, required: true },
country: { type: String, required: true },
},
paymentMethod: {
type: String,
required: true,
},
paymentResult: {
id: { type: String },
status: { type: String },
update_time: { type: String },
email_address: { type: String },
},
taxPrice: {
type: Number,
required: true,
default: 0.0,
},
shippingPrice: {
type: Number,
required: true,
default: 0,
},
itemsPrice: {
type: Number,
required: true,
default: 0,
},
totalPrice: {
type: Number,
required: true,
default: 0,
},
isPaid: {
type: Boolean,
required: true,
default: false,
},
paidAt: {
type: Date,
},
isDelivered: {
type: Boolean,
required: true,
default: false,
},
deliveredAt: {
type: Date,
},
},
{
timestamps: true,
}
);
export const Order= mongoose.model("Order", orderSchema);
enter image description here

Advanced search with mongoose

I have an query object
const query = {
brand : BMW,
yearFrom : 2000,
yearTo : 2003,
price : 7000,
};
I am trying to find every BMW which is made between 2000 and 2003 included.
I am trying in this way but it doesn't work
if (query.yearFrom) {
return offerModel.find({query,year : {$gte : query.yearFrom }}, function(err,arr) {console.log(err,arr)}).skip(offset).limit(12);
}
Here's the mongoose schema
const mongoose = require('mongoose');
const offerSchema = new mongoose.Schema({
brand: {
type: String,
required: true,
},
model: {
type: String,
required: true,
},
year: {
type: Number,
required: true,
},
color: {
type: String,
required: true,
},
power: {
type: Number,
required: true,
},
mileage: {
type: Number,
required: true,
},
populatedState: {
type: String,
required: true,
},
price: {
type: Number,
required: true,
},
condition : {
type: String,
required: true,
},
doors: {
type: Number,
required: true,
},
description: {
type: String,
required: true,
},
transmission: {
type: String,
required: true,
},
engineType: {
type: String,
required: true,
},
category: {
type: String,
required: true,
},
imageURLs : [],
imageIds : [],
creator: {
type: mongoose.Types.ObjectId,
ref: 'user'
},
})
module.exports = mongoose.model('offers', offerSchema);
Sample data from database
_id:60fe98301b76642e04a31c45,
imageURLs:[],
imageIds : [],
brand:BMW,
model:335,
year:2000,
color:White,
doors:4,
power:130
mileage:30000,
populatedState:Sofia,
price:7000,
condition:Used,
description:qweqweqweqe,
transmission:Automatic gearbox,
engineType:Petrol,
category:Sedan,
creator:60fe97d11b76642e04a31c44,
__v:0,
If i put only query it find brand,model and etc.But it doesn't get year search correctly.
I will be glad if you guys have some ideas how can i fix that
Thanks !
Try this
offerModel.find({
$and: [
{ brand :query.brand },
year : {
$gte: query.yearTo,
$lt: query.yearFrom
}
]
}, function (err, results) {
...
}

How to implement type:(new mongoose.Schema) as Array

I have a model for order in my nodejs Application and need to implement in it the number of products which will be in the order.
I have Added The Product type as (new mongoose.Schema) and validate it by Joi, in this case, I can Only add one Product
here is the model of order
const Order = mongoose.model('Order', new mongoose.Schema({
Name: {
type: String,
required: true,
minlength: 3,
maxlength: 50
},
OrderDate: {
type: Date,
default : Date.now
},
Address: {
type: String,
minlength: 3,
maxlength: 50,
required: true,
},
City: {
type: String,
minlength: 3,
maxlength: 50,
required: true,
},
Phone: {
type:Number,
required: true
},
Payment: {
type:String,
required: true
},
OrderPrice: {
type:String,
required: true
},
ShippingPrice:{
type:Number
},
customer: {
type: new mongoose.Schema({
UserName: {
type: String,
required: true,
minlength: 5,
maxlength: 50
},
Email: {
type: String,
unique : true,
required: true,
minlength: 5,
maxlength: 255
},Phone: {
type: Number,
required: true,
min :10
},
Address: {
type: String,
required: true,
minlength: 5,
maxlength: 50
}
}),
required: true
},
product:
{
type: new mongoose.Schema({
Pro_Name: {
type: String,
required: true,
minlength: 5,
maxlength: 50
},
Pro_Price: {
type: Number,
required: true
},
Pro_IMG: {
type: String,
minlength: 5,
maxlength: 50
},
// Pro_Qty: {
// type: Number,
// min: 1
// }
}),
require: true
}
}));
And The Joi validation :
function validateOrder(order) {
const schema = {
Name: Joi.string().min(3).required(),
Address: Joi.string().required(),
City: Joi.string().required(),
Phone: Joi.number().required(),
Payment: Joi.string().required(),
OrderPrice: Joi.number().required(),
customerID:Joi.objectId(),
productID:Joi.objectId(),
};
return Joi.validate(order, schema);
}
Also the rout for creating the order
router.post('/', async(req, res)=>{
const {error} = validate(req.body);
if (error) return res.status(404).send(error.details[0].message);
const customer = await Customer.findById(req.body.customerID);
if (!customer) return res.status(400).send('Invalid customer Pleas Login First.');
const product = await Product.findById(req.body.productID);
if (!product) return res.status(400).send('Invalid Product to be add in the cart');
//create the new Product
let newOrder = new Order({
Name: req.body.Name,
Address: req.body.Address,
City: req.body.City,
Phone: req.body.Phone,
Payment: req.body.Payment,
OrderPrice: req.body.OrderPrice,
customer: {
_id: customer.id,
UserName: customer.UserName,
Email:customer.Email,
Phone:customer.Phone,
Address:customer.Address
},
product: {
_id: product.id,
Pro_Name: product.Pro_Name,
Pro_Price:product.Pro_Price,
Pro_IMG:product.Pro_IMG
}
});
// try{
// new Fawn.Task()
// .save('orders' , newOrder)
// .update('product' , {_id:Product._id},{
// $inc: {numberInStock : -1 }
// })
// .run();
// res.send(newOrder);
// }
// catch(ex){
// res.status(500).send('Somthing bad has happend -_-.')
// }
newOrder = await newOrder.save();
res.send(newOrder);
});
When I Try My Code by Postman The Input
{
"Name": "Hend Mohammed",
"Address": "This is Forth adress",
"City": "Giza",
"Phone": 12345689,
"Payment": "By HEND ^_^ With products and data a bout the customer",
"OrderPrice": 50000,
"customerID":"5cb18f625a9de34582475b22",
"productID" :"5ca11d5f9456812c79d21be6"
}
and The output like
{
"_id": "5cb1a3b7c05d72523925bbac",
"Name": "Hend Mohammed",
"Address": "This is Forth adress",
"City": "Giza",
"Phone": 12345689,
"Payment": "By HEND ^_^ With products and data a bout the customer",
"OrderPrice": "50000",
"customer": {
"_id": "5cb18f625a9de34582475b22",
"UserName": "heba Mohammed",
"Email": "hebs47852#gmail.com",
"Phone": 12345678910,
"Address": "1235Adress"
},
"product": {
"_id": "5ca11d5f9456812c79d21be6",
"Pro_Name": "Cake updated",
"Pro_Price": 100,
"Pro_IMG": "Cake Image"
},
"OrderDate": "2019-04-13T08:54:15.994Z",
"__v": 0
}
This Give me permission to add one product But I need To add more than one product in the Order
Define like this, create new object schema productSchema
const productSchema = new mongoose.Schema({
Pro_Name: {
type: String,
required: true,
minlength: 5,
maxlength: 50
},
Pro_Price: {
type: Number,
required: true
},
Pro_IMG: {
type: String,
minlength: 5,
maxlength: 50
}
});
Assign this scheme into your orderschema to product.
const model = new mongoose.Schema({
Product: [productSchema] <-- it will be as a array of objects
});
const Order = mongoose.model("Order", model);
Product then will act as a Array of object to store multiple products.

Resources