mongoose function .save() is not working .
async function insertContainerizedData(data, id, farmerId) {
console.log('test id: ', new ObjectId(id));
const user = await Storage.findOne({'containerizedBatches.storage_id': new ObjectId(id)});
console.log('userrrr', user);
if (user == null) {
const containerizedBatched = await Storage.updateOne({'farmer_id': farmerId}, {
$push: {
containerizedBatches: {
storage_id: new ObjectId(data.storage_id),
trace_id: data.trace_id,
batch_id: data.batch_id,
actual_quantity: data.actual_quantity,
remaining_quantity: data.remaining_quantity,
actual_container: data.actual_container,
remaining_container: data.remaining_container,
container_type: data.container_type,
grade: data.grade
}
}
});
const result = await containerizedBatched.save(async (err, result) => {
if (err) {
throw new Error('item is not saved');
} else {
return result;
}
});
console.log('result after push', result);
return result;
its my code and the output is as bellow in postman
What iam trying to do is if the user == null i need to push all the data(req.body) into a array as an object and name of the array is containerizedBatches.
"debugMessage": "containerizedBatched.save is not a function",
You don't need to save after you have already run the update. containerizedBatched is the result of your update operation, not a model to save.
Related
I am new to React and I am currently facing an issue that I have API written in Express.js in which I am receiving ur fetching whatever it is called an image uploaded from mobile device in a buffer Array and now I have to convert it into string and add extension to it (let say .jpg) and store it into MongoDB Atlas here is my API written in Express ```module.exports.submitFormDataFile = async (req, res) => {
var hkeyArray = [];
const body = req.body;
const collection_name = body.form_collect_name;
const formstructureresult = await FormsStructure.findOne({
collection_name: collection_name
});
formstructureresult.formdata.forEach((eachData) => {
if (eachData.element === 'file') hkeyArray.push(eachData.hkey);
});
// console.log(hkeyArray)
hkeyArray.forEach((element) => {
//In this part I was supposed to convert it in string and save with extension
console.log(req.files[element].data);
});
if (body._id != '' && body._id != null) {
try {
const result = db.collection(
collection_name
);
const results = await result.findOne({
_id: mongoose.Types.ObjectId(body._id)
});
if (!results) {
res.status(200).json({
ERROR: 1,
MESSAGE: 'Invalid Record'
});
} else {
delete body._id;
var newvalues = { $set: body};
const resu = await result.updateOne(results, newvalues);
if (!resu) {
res.status(404).json({
ERROR: '1',
MESSAGE: 'Unable to update'
});
} else {
res.status(200).json({
SUCCESS: '1',
MESSAGE: 'Record Updated Successfully'
});
}
}
} catch (error) {
console.log(error, 'error');
}
}
};
As everything is dynamic so I am fetching hkey which are the name in MongoDB from a collection and fetching other collection based on req.body received and byteArray is also received from req.body and conversion of it into a string I have to update document as shown in the code
Probleum solved! In my case solution was simple I just changed the code accordingly
hkeyArray.forEach((element) => {
//In this part I was supposed to convert it in string and save with extension
var imagedata = req.files[element].data;
let buff = new Buffer.from(imagedata , 'base64');
fs.writeFile(`element+'.jpg'`,buff, function (err) {
if (err) throw err;
console.log('Saved!');
});
body[element] = element+'.jpg'
});
I'm beginner at programing and I don't know how can I do something with the mongoose save result.
In my post endpoint I would like to not save and directly return but instead of it I would like to do something with the result of save method like take the _id value of the new object created and pass to a function.
Here's what my post endpoint is doing and I would like to after saving not return but instead call a function passing the checkout object created:
router.post('/', async function(req, res) {
const { checkinId, eventId, email } = req.body;
let CheckoutTest = {
checkinId: checkinId,
eventId: eventId,
email: email,
}
const newCheckout = new Checkout(CheckoutTest);
await newCheckout.save((err, checkout) => {
if(err) {
return res.status(400)
.send(err);
}else {
return res.status(200)
.json({message: "Checkout successfully added!", checkout});
}
})
});
An elegant way to do this would be to add a try...catch block
router.post('/', async function(req, res) {
const { checkinId, eventId, email } = req.body;
let CheckoutTest = {
checkinId: checkinId,
eventId: eventId,
email: email,
}
const newCheckout = new Checkout(CheckoutTest);
try {
const newCheckoutObject = await newCheckout.save()
// Call the function that you wanted to after the save.
// You can pass in the "_id" of the object as shown here
const newData = await functionToBeCalled(newCheckoutObject._id)
return res.status(200).json({message: "Checkout successfully added!", newData});
} catch (err) {
return res.status(400).send(err);
}
}
I'm developing a web application using nodejs socket.io and angular 9. In my backend code I have written sockets in socket.connect.service.
Follows is a socket I'm using
socket.on('request-to-sit-on-the-table', async function (data, callback) { //Previously Register
let table = persistence.getTable(tableToken);
if (typeof table === 'undefined') {
let errMsg = 'This table does not exists or already closed.'
callback(prepareResponse({}, errMsg, new Error(errMsg)));
return;
}
//TODO: Get the displayName from the token.
let guest = await guestUserService.getGuestUserByPlayerToken(JSON.parse(data.userToken));***//Here is the issue***
// let displayName = 'DisplayName-' + guest;
let displayName = 'DisplayName-' + Math.random();
//TODO: Check whether the seat is available
// If the new screen name is not an empty string
let isPlayerInCurrentTable = persistence.isPlayerInCurrentTable(tableToken, userToken);
if (displayName && !isPlayerInCurrentTable) {
var nameExists = false;
let currentPlayersTokenArr = persistence.getTableObjectPlayersToken(table)
for (var token in currentPlayersTokenArr) {
let gamePlayer = persistence.getPlayerPlayer(currentPlayersTokenArr[token])
if (typeof gamePlayer !== "undefined" && gamePlayer.public.name === displayName) {
nameExists = true;
break;
}
}
if (!nameExists) {
//Emit event to inform the admin for requesting to sit on the table.
let ownerToken = persistence.getTableObjectOwnerToken(table);
let ownerSocket = persistence.getPlayerSocket(ownerToken);
ownerSocket.emit('requested-to-sit', {
seat: data.seat,
secondaryUserToken: userToken,
displayName,
numberOfChips: envConfig.defaultNumberOfChips
});
callback(prepareResponse({userToken}, 'Player connected successfully.'));
} else {
callback(prepareResponse({}, 'This name is already taken'));
}
} else {
callback(prepareResponse({}, 'This user has already joined to a game. Try clear caching'));
}
});
In my code I'm getting data from another code in guest.user.service. But I get undefined to the value of "guest"
Follows are the methods I have used in guest.user.service
exports.findById = (id) => {
return new Promise(function(resolve, reject) {
guestUserModel.findById(id, (err, data) =>{
if(err){
reject(err);
} else {
resolve(data);
}
});
});
};
exports.getGuestUserByPlayerToken = (playerToken) => {
var player = playerService.findOne({ token: playerToken })
.then(function (data) {
return self.findById(data.guestUser._id.toString());
})
.then(function (guestUser) {
return guestUser.displayName;
})
.catch(function (err) {
throw new Error(err);
})
};
Although I get my displayName for the return value It is not passed to the "guest" in my socket.Is there any syntax issue to get data as I'm using promises.please help
exports.getGuestUserByPlayerToken = async playerToken => {
try {
let player = await playerService.findOne({token:playerToken});
return playerService.findById(player.guestUser._id)
} catch(error) {
console.log(error);
return null;
}
};
This is just handle error on awaited promise not returned one. You need to handle that in caller side.
Here i am iterating an array and save it i database. After completion of iteration, i have to send the response to front end only once(not inside the loop), here is my code. I am declaring a boolean called create quest to false; after iterating all the element in array i have to return response by checking boolean if true? But before completing the loop, below if condition is executing/ so that time boolean is still false; after that line number 9 will start executing.
createQuest = false;
questionList.forEach(element => {
var quest = new Questionnaire({
_id: new mongoose.Types.ObjectId(),
question: element.question,
blockId: blockId
});
quest.save((err1, doc1) => {
9: if(!err1){
createQuest = true;
}else{
res.send({'message':'failed'});
}
})
});
if(createQuest == true){
res.send({'message':'success'});
}
Run multiple parallel task for by iterating over array ( any collection ) and once all of them are finish execute something else
Consider a scenario where you need to Update multiple. You have questions pushed in an array and you want to execute all function dependent of each other.
Solution : Use async.eachSeries()
Here is code to explain same
var async = require('async');
async.eachSeries(questionList,function(element ,eachCb) {
var quest = new Questionnaire({
_id: new mongoose.Types.ObjectId(),
question: element.question,
blockId: blockId
});
quest.save((err1, doc1) => {
if(!err1){
counter++;
}else{
counter++;
return eachCb(err1);
}
eachCb();
})
},function(err,data) {
if(err){
console.log(err);
}
// Once all done, comes here.
});
For Reference Check with
https://codeforgeek.com/asynchronous-programming-in-node-js/
https://dzone.com/articles/how-to-interact-with-a-database-using-the-async-mo
async.eachSeries in node.js
(OR)
Here are both way of saving data with insertMany and save
1) Mongoose save array of documents with insertMany in bulk
db.collection.InsertMany()
var Questionnaire= mongoose.model('Potato', Questionnaire);
write this api in routes directory
router.post('/addDocuments', function (req, res) {
const data = [/* array of object which data need to save in db */];
Questionnaire.insertMany(data)
.then((result) => {
console.log("result ", result);
res.status(200).json({'success': 'new documents added!', 'data': result});
})
.catch(err => {
console.error("error ", err);
res.status(400).json({err});
});
})
BY the way you are implemented you can do the following:
var counter = 0;
questionList.forEach(element => {
var quest = new Questionnaire({
_id: new mongoose.Types.ObjectId(),
question: element.question,
blockId: blockId
});
quest.save((err1, doc1) => {
if(!err1){
counter++;
}else{
counter++;
//res.send({'message':'failed'});
}
})
if(counter == questionList.length) {
res.send({'message':'success'});
}
});
Also you can use promise.all to implement this.
If your purpose is to save all the quests and then send the response then this is what you can do:
let createQuest = false;
let quests = questionList.filter(element => {
return {
_id: new mongoose.Types.ObjectId(),
question: element.question,
blockId: blockId
});
});
Questionnaire.create(quests, function(err) {
if(err)
return res.send({'message':'failed'});
res.send({'message':'success'});
});
My code is as shown below:
checkAndCreateUser(customer_id, email_id).then(result => {
console.log("result is " + result);
});
var checkAndCreateUser = function (custom_id, email) {
return new Promise(function (resolve, reject) {
if ((!custom_id) && (custom_id.trim() == '')) {
var creatUser = new user();
// creatUser._id = user_id;
creatUser.ph_no = ph_no;
creatUser.email_id = email;
console.log("fn works");
user.findOne({
'email_id': email
}, function (err, user) {
console.log("db test");
if (!user) {
creatUser.save(function (err, userInfo) {
if (err) {
reject("no id found");
} else {
customer_id = userInfo._id;
resolve(customer_id);
}
});
} else {
customer_id = user._id;
resolve(customer_id);
}
});
}
});
}
Now what happens here is I am not able to successfully run db query. I am able to get console.log("fn works") printed , but it does not print console.log("db test"). So what exactly is going wrong?
You forgot save your user, besides Mongoose already returned promise, you don't need use callbacks:
var checkAndCreateUser = function (custom_id, email) {
return User.create({ ph_no :ph_no,
email_id :email})
.then(result=>{
return User.findOne({'email_id': email})
})
.then(user=>{
return user._id;
})
};
As for mistake in your function:
...
let user = new User({email_id: email, ph_no: phone});
user.save();//you forgot about this
...
You can use save() with callback:
user.save((err, result)=>{...});
Or with promise:
user.save().then(result=>{...}).catch(err=>{...});