I'm trying to update a new field of data into an existed document, but some of the data is not updating.
In my AngularJS controller:
$scope.tellUsMore = function(){
var data = {
businessPhone:$scope.usersData.phone,
businessEmail:$scope.usersData.email,
businessFb:$scope.usersData.fb,
businessTwitter:$scope.usersData.twitter,
businessInstagram:$scope.usersData.instagram,
businessAboutUs:$scope.usersData.aboutUs,
businessTags:$scope.tags,
businessFeatures:$scope.features,
businessLocation:$scope.usersData.location,
businessPriceRange:$scope.usersData.priceRange,
businessPreparationTimeRange:$scope.usersData.preparationTimeRange
}
console.log(data); //result below
Account.updateProfile(data)
.success(function() {
alert("DONE")
})
.error(function(error) {
console.log(error)
});
}
the console.log(data) result on chrome console tab
Object
businessAboutUs: "LOL"
businessEmail: "example#gmail.com"
businessFb: undefined
businessFeatures: Array[5]
businessInstagram: undefined
businessLocation: Object
businessPhone: "0123456789"
businessPreparationTimeRange: 2
businessPriceRange: 2
businessTags: Array[2]
businessTwitter: undefined
__proto__: Object
In my Node.js server
this.updateProfile = function(req, res, next){
var data = req.body;
console.log(data)//result below
User.update(req.user, {$set: { businessDetails:data }}, {upsert: true}, function(err,user){
res.status(200);
});
}
the console.log(data) result in my terminal
{ businessPhone: '0123456789',
businessEmail: 'example#gmail.com',
businessAboutUs: 'LOL',
businessTags:
[ { name: 'Marina Augustine',
email: 'm.augustine#exampleas.com',
image: 'http://lorempixel.com/50/50/people?0',
_lowername: 'marina augustine' },
{ name: 'Oddr Sarno',
email: 'o.sarno#exampleas.com',
image: 'http://lorempixel.com/50/50/people?1',
_lowername: 'oddr sarno' } ],
businessFeatures:
[ { id: 1, title: 'Do you accept credit card ?', selected: true },
{ id: 2,
title: 'Do you accept table reservation ?',
selected: false },
{ id: 3,
title: 'Do you provide Wi-Fi for your customer ?',
selected: false },
{ id: 4, title: 'Is your product Halal ?', selected: true },
{ id: 5,
title: 'Do you provide parking for your customer ?',
selected: true } ],
businessLocation: { latitude: 3.1168450143582223, longitude: 101.60914228515628 },
businessPriceRange: 2,
businessPreparationTimeRange: 2 }
However, this is what I got – only businessLocation updated to businessDetails, and the businessLocation is not even complete.
> db.users.find().pretty()
{
"_id" : ObjectId("554eb9a8bfa096290c9efa46"),
"companyName" : "t and co",
"email" : "example#gmail.com",
"password" : "$2a$10$79b.XztwEXgdCPDxTkg4ieICSkYyKw4uXG/2E0WShSZxXVdGdwObm",
"dateJoined" : ISODate("2015-05-10T01:51:36.120Z"),
"accountVerified" : false,
"locationVerified" : false,
"__v" : 0,
"businessDetails" : {
"businessLocation" : {
}
}
}
>
schema for user
var userSchema = new db.Schema({
email: { type: String, unique: true, lowercase: true },
password: { type: String, select: false },
companyName: String,
locationVerified: { type:Boolean, default:false},
accountVerified: { type:Boolean, default:false},
dateJoined: {type:Date, default:Date.now}
})
value of req.user
554eb9a8bfa096290c9efa46 this is an objectID in mongodb
You need to define the businessDetails subdoc in userSchema if you want to be able to update it:
var userSchema = new db.Schema({
email: { type: String, unique: true, lowercase: true },
password: { type: String, select: false },
companyName: String,
locationVerified: { type:Boolean, default:false},
accountVerified: { type:Boolean, default:false},
dateJoined: {type:Date, default:Date.now},
businessDetails: {
businessPhone: String,
businessEmail: String,
businessAboutUs: String,
businessTags: [],
businessFeatures: [],
businessLocation: {
latitude: Number,
longitude: Number
},
businessPriceRange: Number,
businessPreparationTimeRange: Number
}
})
Related
I have created the following schema in MongoDB. It is a customer schema with a sub-schema for storing the transactions. Each transaction is an object and each object(a transaction) contains a field called "transactionDetails", which is an object as well.
const transactionSchema = new Schema(
{
transactionType: {
type: String,
},
transactionDetails: {
transferredFrom: {
type: String,
default: "",
},
transferredTo: {
type: String,
default: "",
},
balance:{
type: Number,
default:0,
min: 0,
},
amount:{
type:Number,
default:0
}
},
},
{
timestamps: true,
}
);
const customerSchema = new Schema(
{
name: {
type: String,
required: [true, "Please provide a customer name"],
},
dob: {
type: Date,
required: [true, "Please provide a Date of Birth"],
},
address: {
type: String,
default: "India",
},
accNo: {
type: String,
required: true,
default: mongoose.Types.ObjectId,
},
email: {
type: String,
required: [true, "Please provide an email address"],
},
phone: {
type: String,
required: [true, "Please provide a phone number"],
},
transactions: [transactionSchema],
currentBal: {
type: Number,
required: [true, "Please provide valid balance"],
default: 0,
min:0
},
},
{
timestamps: true,
}
);
All I want to do is to set the value of a field to an existing field in the document while updating it. I want to set the value of "balance" field to the current updated value of the "currentBal" after the "currentBal" field has been updated.
The problem is that the no matter what I did, the value of "balance" field always set to default value without throwing any error
Customer.findOneAndUpdate(
{ accNo: id },
{
$inc: { currentBal: Number(amount),
},
$push: {
transactions: {
transactionType: "deposit",
transactionDetails: {
transferredFrom: "Self",
transferredTo: "Self",
balance:{currentBal} ,
amount: Number(amount),
},
},
},
},
(err, customer) => {
if (err !== null && err.name === "ValidationError") {
res.json({ message: err._message });
} else {
console.log("Balance has been updated successfully");
// console.log(customer.currentBal);
res.redirect(`/customers/${id}`);
}
}
);
I have review and product model.If user give review on specific product(id) then it is stored in review model database but i donot like to store user review in product model database .so, i used virtual populate in product model instead of child referencing.After using virtual properties,if we use product id to see details,we can see review of user in json format but not saved in database.But the problem is my virtual properties (In Product Model) not working as it doesnt show review of user in json format when i send the request in that product id which already have review by user(stored in review model database).what is the problem here?
User Review on Product (id) stored in database
Sending Request of that product id to see review of user in json format using virtual properties(but no review found in json)
In Product Model
const productSchema = new Schema({
name: {
type: String,
required: true,
trim: true,
},
slug: {
type: String,
required: true,
unique: true,
},
price: {
type: String,
required: true,
},
quantity: {
type: Number,
required: true,
},
description: {
type: String,
required: true,
trim: true,
},
offer: {
type: Number,
},
discount: {
type: Number,
},
productPictures: [{
img: {
type: String,
},
}, ],
mainCategory: {
type: mongoose.Schema.Types.ObjectId,
ref: "category",
required: [true, "It is a required field"],
},
sub1Category: {
type: mongoose.Schema.Types.ObjectId,
ref: "category",
required: [true, "It is a required field"],
},
sub2Category: {
type: mongoose.Schema.Types.ObjectId,
ref: "category",
required: [true, "It is a required field"],
},
createdBy: {
type: mongoose.Schema.Types.ObjectId,
ref: "admin",
required: true,
},
vendor: {
type: mongoose.Schema.Types.ObjectId,
ref: "vendor",
},
createdAt: {
type: String,
default: moment().format("DD/MM/YYYY") + ";" + moment().format("hh:mm:ss"),
},
updatedAt: {
type: String,
default: moment().format("DD/MM/YYYY") + ";" + moment().format("hh:mm:ss"),
},
},
{
toJson: { virtuals: true },
toObject: { virtuals: true },
}
);
productSchema.virtual("reviews", {
ref: "review",
foreignField: "product",
localField: "_id",
// justOne: true
});
const Product = mongoose.model("product", productSchema);
module.exports = Product;
In Review Model
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const moment = require("moment");
const reviewSchema = new Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "user",
required: [true, "Review must belong to user"],
},
product: {
type: mongoose.Schema.Types.ObjectId,
ref: "product",
required: [true, "Review must belong to the product"],
},
review: {
type: String,
required: [true, "Review cannot be empty"],
},
rating: {
type: Number,
min: 1,
max: 5,
},
createdAt: {
type: String,
default: moment().format("DD/MM/YYYY") + ";" + moment().format("hh:mm:ss"),
},
updateddAt: {
type: String,
default: moment().format("DD/MM/YYYY") + ";" + moment().format("hh:mm:ss"),
},
}, {
toJson: { virtuals: true },
toObject: { virtuals: true },
});
// pre middleware and populating user and product(we can also do populate in getAllReview in controller)
reviewSchema.pre(/^find/, function(next) {
// ^find here is we use regex and can able to find,findOne ...etc
this.populate({
path: "product",
select: " _id name",
}).populate({
path: "user",
select: " _id fullName",
});
next()
});
const Review = mongoose.model("review", reviewSchema);
module.exports = Review;
In Review.js
const Review = require("../../models/Review.Models")
exports.createReview = async(req, res) => {
const review = await Review.create(req.body)
return res.status(201).json({
status: true,
review
})
}
exports.getAllReviews = async(req, res) => {
try {
const reviews = await Review.find()
return res.status(200).json({
status: true,
totalReviews: reviews.length,
reviews
})
} catch (error) {
return res.status(400).json({
status: false,
error
})
}}
In Product.js
const Product = require("../../models/Product.Models");
exports.getProductDetailsById = async(req, res) => {
try {
const { productId } = req.params;
// const { productId } = req.body;
if (productId) {
const products = await Product.findOne({ _id: productId })
.populate('reviews')
return res.status(200).json({
status: true,
products,
});
} else {
console.log("error display");
return res.status(400).json({
status: false,
error: "params required...",
});
}
} catch (error) {
return res.status(400).json({
status: false,
error: error,
});
}
try this in Product.js
try {
if (productId) {
const products = await Product.findOne({ _id: productId }).populate(
"reviews"
);
console.log(products);
if (products) {
return res.status(200).json({
status: true,
message: "Products is listed",
products,
reviw: products.reviews,
});
only need to add on response sending
return res.status(200).json({
status: true,
message: "Products is listed",
products,
reviw: products.reviews,
});
Banging my head against the wall and I know it's gotta be something stupid...
I have a basic comment(review)/voting system. I am pulling the reviews from the mongo db and in an asysnc.waterfall function, trying to add the votes to each review. Here is the function that adds the votes:
function(reviews, callback) {
let newReviews = [];
_.forEach(reviews, function(review,idx) {
Vote.find({review:review._id}).exec(function(err1, votes){
if (err1){
callback(err1,null);
}else{
console.log("1: REVIEW - ", review);
review.votes = votes;
console.log("2: VOTES - ", review.votes);
newReviews.push(review);
console.log("3: REVIEW - ", review);
if( newReviews.length == reviews.length ){
callback(null,newReviews);
}
}
});
});
}
The votes item never gets populated even though there's data there. Here's some output from those logging statements:
1: REVIEW - { _id: 5a2086139c3c077e546622,
user:
{ passProfileImageURL: '/modules/users/client/img/profile/default.png',
_id: 5a15cd47b9fd942e50e5b,
provider: 'local',
username: 'xxx',
profileImageURL: '/modules/users/client/img/profile/default.png' },
beach:
{ _id: 57995db6666f1ec6f3750,
slug: 'carmel-city-beach-carmel-by-the-sea-california-united-states',
Name: 'Carmel City Beach' },
totalVotes: 1,
reports:
[ { _id: 5a2087f672107f48dd4ed,
user: 5a15cd47db50942e50e5b,
review: 5a208639c3c077e546622,
__v: 0,
updated: 2017-11-30T22:36:38.598Z,
created: 2017-11-30T22:36:38.598Z } ],
created: 2017-11-30T22:30:14.276Z,
comment: 'Why am i doing this???',
rating: 3 }
2: VOTES - [ { _id: 5a26fab26a6f85b39484,
review: 5a20867c3c077e546622,
Type: 'review',
user: 5a15cd4db50942e50e5b,
__v: 0,
updated: 2017-12-05T19:59:46.318Z,
created: 2017-12-05T19:59:46.318Z,
IsVote: true } ]
3: REVIEW - { _id: 5a208676139c3c077e546622,
user:
{ passProfileImageURL: '/modules/users/client/img/profile/default.png',
_id: 5a15cd47b50942e50e5b,
provider: 'local',
username: 'mit',
profileImageURL: '/modules/users/client/img/profile/default.png' },
beach:
{ _id: 579db6666fcec6f3750,
slug: 'carmel-city',
Name: 'Carmel City' },
totalVotes: 1,
reports:
[ { _id: 5a2087b107f48dd4ed,
user: 5a15cfdb50942e50e5b,
review: 5a208673c077e546622,
__v: 0,
updated: 2017-11-30T22:36:38.598Z,
created: 2017-11-30T22:36:38.598Z } ],
created: 2017-11-30T22:30:14.276Z,
comment: 'Why am i doing this???',
rating: 3 }
Doesn't make sense that the number 2 item would log correctly, but 3 does not...can anyone help me make sense of this stupid issue? Or is it just me? LOL
As requested, here's the Vote mongoose schema definition:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var config = {
Type: {
type: String
},
IsVote: {
type: Boolean,
default: true
},
created: {
type: Date,
default: Date.now
},
updated: {
type: Date,
default: Date.now
},
owner: {
type: Schema.ObjectId
},
user: {
type: Schema.ObjectId,
ref: 'User'
},
review: {
type: Schema.ObjectId,
ref: 'Review'
}
};
var VoteSchema = new Schema(config, {
collection: 'votes'
});
/**
* Hook a pre save method to hash the password
*/
VoteSchema.pre('save', function(next) {
next();
});
VoteSchema.method('toggleVote', function() {
this.IsVote = !this.IsVote;
return this.save();
});
VoteSchema.static('createFromReview', function(reviewId, user) {
return new this({
review: reviewId,
Type: 'review',
user: user
});
});
mongoose.model('Vote', VoteSchema);
I have the following Scheme:
dGroup = new SimpleSchema({
title: { type: String, optional: true },
element: { type: String, optional: true }
});
MongoDB.attachSchema(new SimpleSchema({
title: { type: String },
slug: { type: String, unique: true },
language: { type: String, defaultValue: "en" },
group: { type: [dGroup], optional: true },
}));
... and in the DB I got this:
{ "_id" : "ag9qXWpCYm87kZbEk", "title" : "Test", "slug" : "test", "language" : "en" }
Now I want to add a dGroup -> title:
updates['group.title'] = 'insert this as a new group title with no element';
MongoDB.update({ _id: Id }, { $push: updates }, function(error) { if(error) console.warn(error); });
But this doesn't work. So I need some help to add subdocuments in meteor in case they do not exist.
Try declaring your object first and push it properly, like this:
var newGroup = {
title: 'insert this as a new group title with no element'
};
MongoDB.update({ _id: Id }, { $push: {group: newGroup }}, function(error) { if(error) console.warn(error); });
I'm learning MeanJS and I have problem with Mongoose. I have two models:
var CategorySchema = new Schema({
name: {
type: String,
default: '',
required: 'Please fill Category name',
trim: true
},
slug: {
type: String,
default: '',
trim: true,
unique: true
},
created: {
type: Date,
default: Date.now
},
user: {
type: Schema.ObjectId,
ref: 'User'
},
articles: [{
type: Schema.ObjectId,
ref: 'Article'
}]
});
var ArticleSchema = new Schema({
created: {
type: Date,
default: Date.now
},
category: {
type: Schema.ObjectId,
ref: 'Category'
},
title: {
type: String,
default: '',
trim: true,
required: 'Title cannot be blank'
},
slug: {
type: String,
default: '',
trim: true,
unique: true
},
content: {
type: String,
default: '',
trim: true
},
user: {
type: Schema.ObjectId,
ref: 'User'
}
});
I'm saving articles like this:
exports.create = function(req, res) {
var article = new Article(req.body);
article.user = req.user;
article.save(function(err) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
Category.findById(article.category).exec(function(err, category) {
category.articles.push(article.category);
category.save(function(err, category) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.json(article);
}
});
});
}
});
};
and it's saving properly. The object looks like this:
{
"_id" : ObjectId("55b73bf97aa70c2c083655b0"),
"user" : ObjectId("55b115f35c7a03cc0e59d821"),
"articles" : [
ObjectId("55b73c017aa70c2c083655b2"),
ObjectId("55b73ee20bab5e8c0c7eadca")
],
"created" : ISODate("2015-07-28T08:23:21.562Z"),
"slug" : "motocycles",
"name" : "Motocycles",
"__v" : 2
}
and even when I'm counting records like {{ category.articles.length }} it's proper amount of articles in category and I can even print ObjectIds in the view. But when I add .populate('articles') like this:
exports.list = function(req, res) {
Category.find().sort('-created').populate('user', 'displayName').populate('articles').exec(function(err, categories) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.jsonp(categories);
}
});
};
the length returns 0, ObjectIds disapears and I have no access to article properties just like there was no articles in category. Any ideas why is that happening?
Additional edit:
mongoose.model('Article', ArticleSchema);
mongoose.model('Category', CategorySchema);
It seems that the problem was with create function. I've changed few things and it started working:
exports.create = function(req, res) {
var article = new Article(req.body);
article.user = req.user;
article.save(function(err, savedArticle) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
Category.findById(article.category).exec(function (err, category) {
category.articles.push(savedArticle);
category.markModified('articles');
category.save(function (err, category) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.json(savedArticle);
}
});
});
}
});
};
I'm curious why it wasn't working even though Category object had proper Article ObjectId's.
First, some changes with regard to variables,schema instances and using ObjectId(The mongoose documentation isn't the best).
var categorySchema = new mongoose.Schema({
name: {
type: String,
required: 'Please fill Category name',
trim: true
},
slug: {
type: String,
trim: true,
unique: true
},
created: {
type: Date,
default: Date.now
},
user: {
type: mongoose.Types.Schema.ObjectId,
ref: 'User'
},
articles: [{
type: mongoose.Types.Schema.ObjectId,
ref: 'Article'
}]
});
var articleSchema = new mongoose.Schema({
created: {
type: Date,
default: Date.now
},
category: {
type: mongoose.Types.Schema.ObjectId,
ref: 'Category'
},
title: {
type: String,
trim: true,
required: 'Title cannot be blank'
},
slug: {
type: String,
trim: true,
unique: true
},
content: {
type: String,
trim: true
},
user: {
type: mongoose.Types.Schema.ObjectId,
ref: 'User'
}
});
You need to export your models if you are using an MV* pattern with separate files for separate concerns. So...
exports.method = mongoose.model('Category',categorySchema);
exports.otherMethod = mongoose.model('Article',articleSchema);
. method and .otherMethod are from nodejs. Not sure about express equivalent or what express itself uses.
Then just name this file and require it using its path.