I have two model files Bank Deposits and Sub account details. From Sub account details I want to get current balance to Bank deposits . I want to do this in mongodb and node js. I am currently aggreagate lookup operation but it is showing the array as empty.
BankdepositModel.js
var mongoose = require("mongoose");
var BankDepositsSchema = new mongoose.Schema(
{
source_sub_account: Array,
amount: Number,
cheque_notes: Number,
to_bank_account: Array,
amount_in_words: String,
bank_Ref_no: String
},
{
timestamps: true
}
);
module.exports = mongoose.model("BankDeposits", BankDepositsSchema);
Subaccountdetailsmodel.js
var mongoose = require("mongoose");
var SubAccountDetailsSchema = new mongoose.Schema(
{
sub_account_name: String,
current_balance: Number,
account: Array
},
{
timestamps: true
}
);
module.exports = mongoose.model("SubAccountDetails", SubAccountDetailsSchema);
Controller.js
var BankDeposits = require("../model/bankdepositmodel");
var SubAccountDetails = require("../model/subaccountsmodel.js");
exports.create1 = (req, res) => {
var BankDeposit = new BankDeposits({
source_sub_account: req.body.source_sub_account,
amount: req.body.amount,
cheque_notes: req.body.cheque_notes,
to_bank_account: req.body.to_bank_account,
amount_in_words: req.body.amount_in_words,
bank_ref_no: req.body.bank_ref_no
});
BankDeposit.save()
.then(data1 => {
res.send(data1);
})
.catch(err => {
res.status(500).send({
message: err.message
});
});
};
//BankDeposit get
exports.find1 = (req, res) => {
BankDeposits.aggregate([
{
$lookup: {
from: "SubAccountDetails",
localField: "current_balance",
foreignField: "current_balance",
as: "balance"
}
}
])
.then(appdata => {
res.status(200).send(appdata); //On successful fetch, server responds with status 200
})
.catch(err => {
res.status(400).send(err); //On error, server responds with status 400
});
};
//sub account details post
exports.createSubAccountDetail = (req, res) => {
var SubAccountDetail = new SubAccountDetails({
sub_account_name: req.body.sub_account_name,
current_balance: req.body.current_balance,
account: req.body.account
});
SubAccountDetail.save()
.then(SubAccountDetail => {
res.send(SubAccountDetail);
})
.catch(err => {
res.status(500).send({
message: err.message
});
});
};
//sub account details get
exports.SubAccountDetail = (req, res) => {
SubAccountDetails.find()
.then(SubAccountDetails => {
res.send(SubAccountDetails);
})
.catch(err => {
res.status(500).send({
message: err.message || "Some error occurred while retrieving regs."
});
});
};
You can get it like this
BankDeposits.aggregate([
{
$lookup: {
from: "SubAccountDetails",
localField: "source_sub_account",
foreignField: "sub_account_name",
as: "sub_acount"
}
}
])
Now you will get your complete sub_account object in sub_account property of returned data, current_balance will be in same
This is assuming that sub_account_name in SubAccountDetails & source_sub_account in BankDeposits are same
Related
Im trying to create an API where users can create their fav movies and rate them.
So instead of creating a Movies array in user model, I created a Movie model with userId as an array. Now the logic is if there is a movie by the same name the new user is trying to create, it will not create a movie, rather it will push the userid and their rating. If there is no movie by that name it will create one. But I am stuck in that part. Any help will be hugely appreciated. Below im posting my code.
Movie model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const movieSchema = new Schema({
title: {
type: String,
required: true,
},
rating: [
{ type: Number, required: true, max: 5 },
],
userId: [
{
type: String,
},
],
});
const Movie = mongoose.model(
'Movie',
movieSchema
);
module.exports = Movie;
user model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema({
name: {
type: String,
required: true,
},
age: {
type: Number,
required: true,
},
// list: {
// type: Array,
// default: [],
// },
});
const User = mongoose.model('User', userSchema);
module.exports = User;
movie route
const router = require('express').Router();
const User = require('../models/User');
const Movie = require('../models/Movies');
//creating a movie
router.post(
'/:id/createmovie',
async (req, res) => {
const { title, rating } = req.body;
const userId = req.params.id;
try {
const currentMovie = await Movie.findOne({
title,
});
if (currentMovie == null) {
const newMovie = new Movie({
title,
rating,
userId,
});
newMovie
.save()
.then((data) => res.json({ data }))
.catch((err) => {
res.status(400).json({ error: err });
});
}
currentMovie
.updateOne(
{ title },
{ $push: { userId, rating } }
)
.then((data) => res.json({ data }))
.catch((err) => {
res.status(400).json({ error: err });
});
} catch (err) {
console.log(err);
}
}
);
// router.post('/:id/createmovie', (req, res) => {
// const { title, rating } = req.body;
// const userId = req.params.id;
// Movie.findOne({ title }).then((data) => {
// console.log(data);
// res.json(data);
// if (data == null) {
// res.send('true');
// }
// res.send('false');
// if (data.title == title) {
// Movie.updateOne(
// { title },
// { $push: { userId, rating } }
// );
// }
// const newMovie = new Movie({
// title,
// rating,
// userId,
// });
// newMovie
// .save()
// .then((data) => res.json({ data }))
// .catch((err) => {
// res.status(400).json({ error: err });
// });
// });
// });
router.get('/getmovie', (req, res) => {
const { title } = req.body;
Movie.find({ title })
.then((data) => res.json(data[0].title))
.catch((err) => {
res.status(400).json({ error: err });
});
});
module.exports = router;
Change router.post function arguments
router.post(
'/:id/createmovie',
async (req, res) => {
const { title, rating } = req.body;
const userId = req.params.id;
try {
const currentMovie = await Movie.findOne({
title,
});
if (currentMovie == null) {
await Movie.insertOne({title ,rating, userId})
.
}
else{
await Movie.updateOne(
{ title },
{ $push: { userId, rating } }
)
}
} catch (err) {
console.log(err);
}
}
);
I want to delete a doc with id in mongoose. It executes the method but doesn't delete that doc in MongoDB Altas.
Note:Everthing is correct and also Passing id correctly in PostMan.
here is my controller :
const Post = require("../models/Post");
const mongoose = require("mongoose");
exports.postPost = async (req, res) => {
try {
const post = await new Post({
_id: new mongoose.Types.ObjectId(),
title: req.body.title,
desc: req.body.desc,
}).save();
console.log("Saved in db!");
return res.status(201).json({
success: true,
data: post,
});
} catch (error) {
return res.status(500).json({
success: false,
message: "Server Error",
});
}
};
exports.deletePost = async (req, res) => {
let postID = req.params.id;
await Post.deleteOne({ _id: postID }, (err, data) => {
if (err) {
res.status(500).json({
message: "Something went wrong, please try again later.",
});
} else {
res.status(200).json({
message: "Post Deleted",
data: data,
});
}
});
};
here is my posts route:
const express = require("express");
const router = express.Router();
const {
postPost,
deletePost,
} = require("../controllers/posts_controller");
router.route("/:id").delete(deletePost);
router.route("/").post(postPost);
module.exports = router;
here is my postman :
here is my mongodb altas:
use the findOneAndDelete({_id:postId}) instead of deleteOne in posts controller
Or
use findByIdAndDelete(postId) instead of deleteOne in posts controller
exports.deletePost = async (req, res) => {
let postID = req.params.id;
await Post.findByIdAndDelete(postID, (err, data) => {
if (err) {
res.status(500).json({
message: "Something went wrong, please try again later.",
});
} else {
res.status(200).json({
message: "Post Deleted",
data: data,
});
}
});
};
exports.clearHours = (req, res, next) => {
Hour
.find({ user: req.body.userId })
.then(hour => {
for (let i=0;i<hour.length;i++) {
hour[i].hours = 0;
}
return hour.save()
})
.then(result => {
res.status(200).json({message: 'Working hours have been successfully updated.'});
})
.catch(err => {
if (!err.statusCode) {
err.statusCode = 500;
}
next(err);
})
};
I am trying to save the formatted array on the database and I get this error. The updated code is passed properly but when I am trying to save the array it comes up with this error. Any ideas why?
This is my hour model:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const hourSchema = new Schema ({
day: {
type: String,
required: true
},
hours: {
type: Number,
required: true
},
user: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
}
});
module.exports = mongoose.model('Hour', hourSchema);
It seems you are fetching the document into memory and re-setting the hour field to 0, better you can run an update query into the database itself.
On top require mongoose -
const mongoose = require('mongoose');
Below is clearHours method refactored.
exports.clearHours = async (req, res, next) => {
try {
const query = {
user: mongoose.Types.ObjectId(req.body.userId)
};
const update = {
$set: {
hours: 0
}
};
await Hour.update(query, update).exec();
res.status(200).json({message: 'Working hours have been successfully updated.'});
} catch (err) {
if (!err.statusCode) {
err.statusCode = 500;
}
next(err);
}
};
I am having some issue with express app when posting to a route, I am trying to pass some dishIds as shown below through the body of POSTMAN:
[
{"_id":"5f209e066e27a49e582b46bc"},
{"_id":"5f209e746e27a49e582b46be"}
]
I am trying to save Favorite dish and the schema is show below (favorite.js)(:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
require('mongoose-currency').loadType(mongoose);
const favoriteSchema = new Schema({
dishes: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Dish'
}],
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
},{
timestamps: true
})
var Favorites = mongoose.model('Favorite', favoriteSchema);
module.exports = Favorites;
I am trying to save user, dishId into Favourites model but I am getting an error that says " Cannot read property 'push' of undefined", Can anyone help me understand what Ia am getting wrong with POST Route below:
thank you in advance.
.post(cors.corsWithOptions, authenticate.verifyUser, (req, res, next) =>{
Favorites.create(req.body)
.then((favorite) => {
if( favorite != null) {
req.body.user = req.user._id // get the current user
favorite.dishes.push(req.body)
favorite.save()
.then((favorite) => {
Favorites.findById(favorite._id)
.populate('user') //populate the user
.then((favorite) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.json(favorite);
})
}, (err) => next(err))
}
else {
err = new Error('Dish ' + req.params.dishId + 'not found');
err.status = 404;
return next(err);
}
}, (err) => next(err))
.catch((err) => next(err));
})
I have created 2 Users(Admin and Users) and also i have created many ToDos for a User but here my Todo array is empty in my User Schema. Unable to understand why todo task are not assigned to the User Schema.
UserSchema
var userSchema = new Schema({
name: {
type: String,
required: true,
maxlength: 30,
trim: true
},
role: {
type: Number,
default: 0
},
todos: [{
type: Schema.Types.ObjectId,
ref:"Todo"
}]
});
module.exports = mongoose.model("User", userSchema)
Todo Schema
let Todo = new Schema({
todo_heading: {
type: String
},
todo_desc: {
type: String
},
todo_priority: {
type: String
},
todo_completed: {
type: Boolean
},
user: {
type: Schema.Types.ObjectId,
ref:"User"
}
})
module.exports = mongoose.model('Todo', Todo);
here are my routes
User Route
router.get("/user/:userId/todos", isSignedIn, isAuthenticated, getToDos)
Todo Route
router.get("/", getTodos)
router.get("/:id", getUsertodos);
router.post("/user/:userId/add", addUsertodos);
User Controllers
exports.getToDos = (req, res) => {
User.find({ _id: req.params._id })
.populate("todos")
.exec((err, toDo) => {
if (err) {
res.json(err)
}
res.json(toDo)
})
}
ToDo Controllers
exports.addUsertodos = (req, res) => {
let todo = new Todo(req.body)
todo.save((err, todo) => {
if (err) {
return res.status(400).json({
error: "not saved"
})
}
else {
return res.json(todo)
}
})
}
it should work as expected if you add the objectId of newly created todo to the todos property when you create a user.
//routers/todo.js
var express = require('express');
var router = express.Router();
const Todo = require('../models/Todo');
const User = require('../models/User');
/* GET home page. */
router.get('/', async function (req, res) {
let todos = await Todo.find();
res.json({
todos
});
});
router.post('/todos', async function (req, res) {
//add todos
let {
todo_desc,
todo_heading,
todo_priority,
todo_completed
} = req.body;
try {
//NOTE: for simplicity assigning first user but you can grab it from the params
let user = await User.findOne();
let todo = await Todo.create({
todo_desc,
todo_completed,
todo_priority,
todo_heading,
user: user._id
})
res.json({
message: 'todo created successfully',
todo
});
} catch (err) {
return res.status(500).json({
message: 'Unable to create a todo',
err: JSON.stringify(err)
})
}
});
module.exports = router;
Here is the user route where post route get the string id of created ID and converts it to ObjectId(), assign it to the todos.
var express = require('express');
var router = express.Router();
let _ = require('lodash');
var mongoose = require('mongoose');
const User = require('../models/User');
/* GET users listing. */
router.post("/", async function (req, res) {
let {
name,
todos
} = req.body;
try {
let user = new User();
user.name = name;
let objectIds = todos.split(',').map(id => mongoose.Types.ObjectId(id));
user.todos.push(...objectIds)
await user.save()
console.log("user: ", JSON.stringify(user));
if (_.isEmpty(user)) {
res.status(500).json({
message: 'unable to create user'
})
}
res.json(user);
} catch (err) {
res.status(500).json({
message: 'unable to create user',
err: JSON.stringify(err)
})
}
});
router.get("/", async function (req, res) {
try {
let user = await User.find().populate('todos');
console.log("user: ", JSON.stringify(user));
if (_.isEmpty(user)) {
res.status(500).json({
message: 'unable to find user'
})
}
res.json(user);
} catch (err) {
res.status(500).json({
message: 'unable to find user',
err: JSON.stringify(err)
})
}
});
module.exports = router;
Check out the attached screenshot, the user record now contains the todos assigned to it.
If you want checkout the working code, please visit this repo that i created!!.
Hope this help.Cheers!!