cant save data after push to a array in acollection - node.js

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

buffer Array to String and then saving in directory

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

Save in mongodb and pass created object to a function

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

use async - await with socket.io nodejs

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.

How to return response only once after iterating over an array in nodejs?

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

why mongoose queries dos not work when put inside promise function

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=>{...});

Resources