Apollo Server Resolver not returning all data (returned data is not complete) - node.js

My setup: Apollo server with express.js
MongoDB with Mongoose
My problem: When I run a query, my resolver is not fetching all of the data, just part of it.
Here is my resolver code:
getMarsContentForScreen: async (_, { screen, token }, context) => {
if (!context.screen) return {};
console.log(screen, token);
const contentOut = {};
const screenExist = await MarsScreen.findOne({
name: screen,
token: token,
});
if (screenExist) {
const content = await MarsContent.findOne({
screens: { $in: screenExist.id },
});
if (content) {
// ID
contentOut.id = content.id;
// NAME
contentOut.name = content.name;
// ENTRY
contentOut.entry = [{ entryVideos: [] }];
content.entry.map(async (val) => {
let file = await Asset.findById(val, 'uri');
if (file && file.uri) {
contentOut.entry[0].entryVideos.push(
file.uri.split('/').slice(-1)[0]
);
}
});
// EQUIPMENT
contentOut.equipment = [];
content.equipment.map(async (val) => {
let equipment = await MarsEquipment.findById(
val.id,
'name thumbnail background'
);
if (equipment) {
contentOut.equipment.push({
id: val.id,
name: equipment.name,
panelImage: equipment.thumbnail.split('/').slice(-1)[0],
productImage: equipment.background.split('/').slice(-1)[0],
});
}
});
// EXERCISES
contentOut.exercises = [];
content.exercises.map(async (val, index) => {
contentOut.exercises.push({
equipment: val.equipment,
content: [],
});
val.content.map(async (valC) => {
let exercise = await MarsExercise.findById(
valC.id,
'name level text thumbnail video'
);
if (exercise) {
let instructions = [];
for (const [key, value] of Object.entries(
JSON.parse(exercise.text)
)) {
instructions.push(value);
}
contentOut.exercises[index].content.push({
id: valC.id,
position: valC.position,
name: exercise.name,
level: exercise.level,
instructions: instructions,
panelImage: exercise.thumbnail.split('/').slice(-1)[0],
programVideo: exercise.video.split('/').slice(-1)[0],
});
}
});
});
// OPTIONS
contentOut.options = [];
let bgImage = await Asset.findById(content.options[0].bgImage, 'uri');
bgImage = bgImage.uri.split('/').slice(-1)[0];
contentOut.options = [
{
bgImage: bgImage,
cards: [],
},
];
content.options[0].cards.map(async (val, index) => {
let cardImg = await Asset.findById(val.panelImage, 'uri');
if (cardImg) {
contentOut.options[0].cards.push({
name: val.name,
panelImage: cardImg.uri.split('/').slice(-1)[0],
subheading: val.subheading,
action: val.action,
});
if (val.overlay) {
contentOut.options[0].cards[index].overlay = val.overlay;
}
if (
val.externalApp &&
val.externalApp.appName &&
val.externalApp.playStoreId
) {
contentOut.options[0].cards[index].externalApp = {
appName: val.externalApp.appName,
playStoreId: val.externalApp.playStoreId,
};
}
}
});
// WORKOUTS
contentOut.workouts = [];
content.workouts.map(async (val) => {
let workout = await MarsWorkout.findById(
val.id,
'name thumbnail video text required'
);
if (workout) {
contentOut.workouts.push({
id: val.id,
position: val.position,
name: workout.name,
panelImage: workout.thumbnail.split('/').slice(-1)[0],
programVideo: workout.video.split('/').slice(-1)[0],
instructions: workout.text,
required: workout.required,
});
}
});
// FILES
contentOut.files = [];
content.files.map(async (val) => {
let file = await Asset.findById(val, 'uri updated_at');
if (file) {
contentOut.files.push({
id: val,
uri: file.uri,
filename: file.uri.split('/').slice(-1)[0],
timestamp: file.updated_at,
});
}
});
return contentOut;
} else {
return {};
}
}
}
Here is the query I'm running in the Playground:
query {
getMarsContentForScreen(screen: "GS123123123123", token: "token-here") {
id
name
entry {
entryVideos
}
equipment {
id
name
position
panelImage
productImage
}
exercises {
equipment
content {
id
position
name
level
panelImage
programVideo
instructions
}
}
options {
bgImage
cards {
name
panelImage
subheading
action
overlay
externalApp {
appName
playStoreId
}
}
}
workouts {
id
position
name
panelImage
programVideo
required
instructions
}
files {
id
filename
uri
timestamp
}
}
}
And here is the output of what I'm getting:
{
"data": {
"getMarsContentForScreen": {
"id": "6203d63f54a0bd82832288c5",
"name": "sdfgsdfg",
"entry": [
{
"entryVideos": [
"6bb847e5-8b9a-477b-bfd1-68a109b3c707.mp4",
"9b1628af-e69e-4d0e-9d53-b472a963a1ec.mp4",
"830b0258-70f1-4206-b07b-fb60508e33c5.mp4"
]
}
],
"equipment": [
{
"id": "62025aa4237005069c569d63",
"name": "dsfgsdfg",
"position": null,
"panelImage": "da245241-335e-4021-929c-d177a851c2ea.jpg",
"productImage": "da245241-335e-4021-929c-d177a851c2ea.jpg"
},
{
"id": "62025afa237005069c569d99",
"name": "sdfgsdfgsdfgsdfgsdfgsdfgweqqwerwr",
"position": null,
"panelImage": "da245241-335e-4021-929c-d177a851c2ea.jpg",
"productImage": "da245241-335e-4021-929c-d177a851c2ea.jpg"
},
{
"id": "62025af4237005069c569d92",
"name": "sdfgsdfgsdfgdsf",
"position": null,
"panelImage": "da245241-335e-4021-929c-d177a851c2ea.jpg",
"productImage": "da245241-335e-4021-929c-d177a851c2ea.jpg"
}
],
"exercises": [
{
"equipment": "dsfgsdfg",
"content": [
{
"id": "62025b27237005069c569dc0",
"position": 1,
"name": "sdfgsdfg",
"level": "Intermediate",
"panelImage": "da245241-335e-4021-929c-d177a851c2ea.jpg",
"programVideo": "6bb847e5-8b9a-477b-bfd1-68a109b3c707.mp4",
"instructions": [
"sdfgsdfg",
"sdfgsdfg",
"sdfg"
]
},
{
"id": "62025b30237005069c569dc7",
"position": 2,
"name": "sdfgsdfgsdfg",
"level": "Intermediate",
"panelImage": "da245241-335e-4021-929c-d177a851c2ea.jpg",
"programVideo": "6bb847e5-8b9a-477b-bfd1-68a109b3c707.mp4",
"instructions": [
"sdfgsdfg",
"sdfg",
"hgfjgh"
]
}
]
},
{
"equipment": "sdfgsdfgsdfgdsf",
"content": [
{
"id": "62025b80237005069c569e13",
"position": 1,
"name": "sdfg",
"level": "Intermediate",
"panelImage": "da245241-335e-4021-929c-d177a851c2ea.jpg",
"programVideo": "6bb847e5-8b9a-477b-bfd1-68a109b3c707.mp4",
"instructions": [
"sdfg",
"sdfgsdfg",
"sdfgdf"
]
}
]
},
{
"equipment": "sdfgsdfgsdfgsdfgsdfgsdfgweqqwerwr",
"content": [
{
"id": "62025b88237005069c569e1a",
"position": 1,
"name": "uitytyui",
"level": "Intermediate",
"panelImage": "da245241-335e-4021-929c-d177a851c2ea.jpg",
"programVideo": "6bb847e5-8b9a-477b-bfd1-68a109b3c707.mp4",
"instructions": [
"ytuityui",
"tyui",
"tyuityuityui"
]
}
]
}
],
"options": [
{
"bgImage": "da245241-335e-4021-929c-d177a851c2ea.jpg",
"cards": []
}
],
"workouts": [],
"files": []
}
}
}
As you can see, everything from "options" : [{"cards"}] is empty, but it shouldn't be, as there is the data in the database for it.
What is even more interesting, is that when I console.log the contentOut object inside the last .map function (content.files.map()) I'm getting the full response.
Basically it looks like my resolver is returning the content before all of it is gathered.
If I add some if statement to check if all of my content is in the contentOut object, I'm getting empty response, just like the resolver couldn't be bothered to wait for all of the content...
Any ideas?
Many thanks in advance!

Ok, so after more Googling and fighting with it, I've re-write the whole code and use Promise.all for each part of the function in order to make sure that it will wait for the outcome of each await, before returning the value.
Now the code looks like this:
getMarsContentForScreen: async (_, { screen, token }, context) => {
if (!context.screen) return {};
console.log(screen, token);
const contentOut = {};
const screenExist = await MarsScreen.findOne({
name: screen,
token: token,
});
const getEntryVideos = async (content) => {
let result = [{ entryVideos: [] }];
await Asset.find({ _id: { $in: content } }, 'uri').then((response) =>
response.map((val) => {
result[0].entryVideos.push(val.uri.split('/').slice(-1)[0]);
})
);
return result;
};
const getEquipment = async (content) => {
let result = [];
const ids = content.map((val) => {
return val.id;
});
await MarsEquipment.find(
{ _id: { $in: ids } },
'id name thumbnail background'
).then((response) =>
response.map((val) => {
result.push({
id: val.id,
name: val.name,
panelImage: val.thumbnail.split('/').slice(-1)[0],
productImage: val.background.split('/').slice(-1)[0],
});
})
);
return result;
};
const getExercises = async (content) => {
let result = [];
const ids = [].concat(
...content.map((val) => {
result.push({
equipment: val.equipment,
content: [],
});
return val.content.map((valC) => {
return valC.id;
});
})
);
await MarsExercise.find(
{ _id: { $in: ids } },
'id name level text thumbnail video product'
).then((response) =>
response.map((exer) => {
let instructions = [];
const index = result.indexOf(
result.find((equip) => equip.equipment === exer.product)
);
for (const [key, value] of Object.entries(JSON.parse(exer.text))) {
instructions.push(value);
}
result[index].content.push({
id: exer.id,
position: exer.position,
name: exer.name,
level: exer.level,
instructions: instructions,
panelImage: exer.thumbnail.split('/').slice(-1)[0],
programVideo: exer.video.split('/').slice(-1)[0],
});
})
);
return result;
};
const getOptions = async (content) => {
let result = content;
const ids = content[0].cards.map((val) => {
return val.panelImage;
});
await Asset.findById(content[0].bgImage, 'uri').then((response) => {
result[0].bgImage = response.uri.split('/').slice(-1)[0];
});
await Asset.find({ _id: { $in: ids } }, 'id uri').then((response) =>
response.map((val) => {
let index = result[0].cards.indexOf(
result[0].cards.find((card) => card.panelImage === val.id)
);
result[0].cards[index].panelImage = val.uri.split('/').slice(-1)[0];
})
);
return result;
};
const getWorkouts = async (content) => {
let result = content;
const ids = content.map((val) => {
return val.id;
});
await MarsWorkout.find(
{ _id: { $in: ids } },
'id name thumbnail video text required'
).then((response) => {
response.map((val) => {
let index = result.indexOf(
result.find((work) => work.id === val.id)
);
result[index].panelImage = val.thumbnail.split('/').slice(-1)[0];
result[index].programVideo = val.video.split('/').slice(-1)[0];
});
});
return result;
};
const getFiles = async (content) => {
let result = [];
await Asset.find({ _id: { $in: content } }, 'id uri updated_at').then(
(response) => {
response.map((val) => {
result.push({
id: val.id,
uri: val.uri,
filename: val.uri.split('/').slice(-1)[0],
timestamp: val.updated_at,
});
});
}
);
return result;
};
if (screenExist) {
const content = await MarsContent.findOne({
screens: { $in: screenExist.id },
});
if (content) {
// ID
contentOut.id = content.id;
// NAME
contentOut.name = content.name;
// ENTRY
const entry = getEntryVideos(content.entry);
// EQUIPMENT
const equipment = getEquipment(content.equipment);
// EXERCISES
const exercises = getExercises(content.exercises);
// OPTIONS
const options = getOptions(content.options);
// WORKOUTS
const workouts = getWorkouts(content.workouts);
// FILES
const files = getFiles(content.files);
// PROMISE
const results = await Promise.all([
entry,
equipment,
exercises,
options,
workouts,
files,
]);
//console.log(results);
return {
id: content.id,
name: content.name,
entry: results[0],
equipment: results[1],
exercises: results[2],
options: results[3],
workouts: results[4],
files: results[5],
};
} else {
return {};
}
}
},

Related

Node - build a tree recursively with API data

I need to build a tree like structure using data from an API.
The structure i start with is as follows:
{
"type": "group",
"id": 1,
"name": "rootGroup",
"members": [],
}
There will always be a root group as the base of the tree.
I have a function named getMembersInGroup(groupId) which is an API call and returns something like:
[
{
"type": "group",
"id": 77,
"name": "IT group",
},
{
"type": "user",
"id": 40,
"name": "John"
}
]
Members can either be of type user or another group. So a user would look like:
{
"type": "user",
"id": 40,
"name": "John"
}
If it's another group it needs to recursively fetch those until there are only users or empty array left in members.
Any group can have users at any level with the tree.
A mock of getMembersInGroup:
const getMembersInGroup = async (groupId) => {
try {
const members = await fetch.callApi('/groups/' + groupId + '/members');
if (members) {
return members;
}
else {
return [];
}
} catch (error) {
return { error };
}
}
The end result should look like this:
{
"type": "group",
"id": 1,
"name": "rootGroup",
"members": [
{
"type": "group",
"id": 88,
"name": "Some group",
"members": [
{
"type": "user",
"id": 231,
"name": "SALLY"
},
{
"type": "user",
"id": 232,
"name": "Henry"
}
]
},
{
"type": "user",
"id": 41,
"name": "Chris"
}
],
}
I need help with the algorithm to create the tree.
Your getMembersInGroup function could look like this:
const getMembersInGroup = async (groupId) => {
const members = (await fetch.callApi(`/groups/${groupId}/members`)) ?? [];
for (const member of members) {
if (member.type == "group") {
member.members = await getMembersInGroup(member.id);
}
}
return members;
}
Call it like this:
async function loadTree() {
return {
type: "group",
id: 1,
name: "rootGroup",
members: await getMembersInGroup(1)
};
}
loadTree().then(result =>
console.log(result);
// Work with the result ...
).catch(error =>
console.log("error: ", error)
);
Demo with a mock implementation of fetch.callApi:
// Mock for fetch.callApi
const fetch = {
mockData: [0,[2,3,4],[5,6,7],[8,9],0,0,0,[10],0,0,[11,12],0,0],
callApi(url) {
return new Promise((resolve, reject) => {
const groupId = +url.split("/")[2];
const children = this.mockData[groupId];
if (!children) return reject("not found: " + groupId);
const result = children.map(id => {
const type = this.mockData[id] ? "group" : "user";
return {type, id, name: type + "_" + id};
});
setTimeout(() => resolve(result), 50);
});
}
}
async function loadTree() {
return {
type: "group",
id: 1,
name: "rootGroup",
members: await getMembersInGroup(1)
};
}
const getMembersInGroup = async (groupId) => {
const members = (await fetch.callApi('/groups/' + groupId + '/members')) ?? [];
for (const member of members) {
if (member.type == "group") {
member.members = await getMembersInGroup(member.id);
}
}
return members;
}
loadTree().then(result =>
console.log(JSON.stringify(result, null, 2))
).catch(error =>
console.log("error: ", error)
);
You can do something like:
const getMembersInGroup = async (groupId) => {
try {
const members = await fetch.callApi('/groups/' + groupId + '/members');
if (members) {
foreach(member in members) {
if (member.type == 'groups') {
member.members = getMembersInGroup(member.groupid)
}
}
return members;
}
else {
return [];
}
} catch (error) {
return { error };
}
}
So you have the recursion only if it's a group type, otherwise the member is returned as is.

Finding items with attribute value match excluding another value in Sequelize

I have this code :
module.exports.MyFunction= async (req, res) => {
let token = req.body.token;
let decoded = jwt_decode(token);
let email = decoded.email;
let data = req.body;
let searchUser = data.user;
try {
let user = await User.findAll({
where: {
[Op.or]: [
{ firstName: searchUser },
{ lastName: searchUser },
{ email: searchUser },
{ publicKey: searchUser },
],
},
attributes: ["firstName", "lastName", "email", "publicKey", "avatar"],
}).then((response) => {
return response;
});
res.json({ user });
} catch (err) {
res.json({ err });
}
};
If I run that code, I get all the users that match with the value passed in searchUser.
What I want to do is to exclude the user object that have a specific email.
For instance, if have multiple users named Michel, I want to get all the users with an email address different of the email variable declared at the top of the function, even if their fisrtName matches.
Problem solved by doing this :
module.exports.MyFunction = async (req, res) => {
let token = req.body.token;
let decoded = jwt_decode(token);
let loggedUserEmail = decoded.email;
let data = req.body;
let searchUser = data.user;
console.log(searchUser);
try {
let user = await User.findAll({
where: {
[Op.or]: [
{
firstName: {
[Op.startsWith]: searchUser,
},
},
{
lastName: {
[Op.startsWith]: searchUser,
},
},
{
email: {
[Op.startsWith]: searchUser,
},
},
{
publicKey: {
[Op.startsWith]: searchUser,
},
},
],
email: {
[Op.ne]: loggedUserEmail,
},
},
attributes: ["firstName", "lastName", "email", "publicKey", "avatar"],
}).then((response) => {
return response;
});
res.json({ user });
} catch (err) {
res.json({ err });
}
};

How to convert for urlencoded array into json in node js

I am having a form-urlencoded request as follows:
but I have to convert this request in json as follows:
{
"version":4.2,
"auth_token": "xxxxxxxx",
"zcontacts":[
{ "phone": "xxxxx", "name": "xxxx" },
{ "phone": "112", "name": "Distress Number" },
{ "phone": "1800-300-xxxx", "name": "UIDAI" },
{ "phone": "44 xxxxx, "name": "Ab zz" }
]
}
Here below is my code which I am trying:
index(req_data) {
const self = this;
return new Promise((resolve, reject) => {
console.log(typeof req_data)
let req_body = {}
req_body.version = req_data.version;
req_body.auth_token = req_data.auth_token;
let contacts_list = [];
return Promise.each(req_data.zcontacts,(contact, key, length) => {
// Logic starts from here
if(key === 0) {
contacts_list.push({
phone: req_data.zcontacts[key],
name: req_data.zcontacts[(key+1)]
})
} else if(key > 0) {
contacts_list.push({
phone: req_data.zcontacts[(key+3)],
name: req_data.zcontacts[(key+4)]
})
}
}).then(() => {
req_body.zcontacts = contacts_list;
resolve(req_body)
});
Can anyone suggest what should be changed in the code under the loop?
I got it:
return Promise.each(req_data.zcontacts,(contact, key, length) => {
if(key % 2 === 0) {
contacts_list.push({
phone: req_data.zcontacts[key],
name: req_data.zcontacts[(key+1)]
})
}
}).then(() => {
req_body.zcontacts = contacts_list;
resolve(req_body)
});

How to modify array on NodeJS

this is my array in model file,
var genres = [
"Action",
"Comedy",
"Documentary"
];
I need to return(res.send) like this,
[
{ label: "Action", value: 1 },
{ label: "Comedy", value: 2 },
{ label: "Documentary", value: 3 },
{ label: "Drama", value: 4 }
];
I wrote get a request like this,
router.get("/genre", (req, res, next) => {
try {
let genre = MovieModel.genres;
res.send(genre);
} catch (e) {
return res.send(e.message);
}
});
You could use Array.map to compose a new array.
router.get("/genre", (req, res, next) => {
try {
res.send(MovieModel.genres.map((genre, index) => { return { label: genre, value: index }; }));
} catch (e) {
return res.send(e.message);
}
});
const genres = [
"Action",
"Comedy",
"Documentary"
];
const newGenres = genres.map((genre, i) => {
return (
{ "label": genre, "value": i + 1 }
)
});
console.log(newGenres);
Gives you:
[
{ label: "Action", value: 1 },
{ label: "Comedy", value: 2 },
{ label: "Documentary", value: 3 },
{ label: "Drama", value: 4 }
];
To return this via res.send:
router.get("/genre", (req, res, next) => {
try {
let genres = MovieModel.genres;
res.send(
genres.map(
(genre, i) => { return { "label": genre, "value": i + 1 };
)
);
} catch (e) {
return res.send(e.message);
}
});
Working well
const arr = ["Action", "Comedy", "Documentary", "Drama"];
arr.map((arrElement, index) => ({ label: arrElement, value: index }));

Update the same property of every document of a mongoDb collection with different values

I have a collection in mongoDb which looks like this
{
"slno" : NumberInt(1),
"name" : "Item 1"
}
{
"slno" : NumberInt(2),
"name" : "Item 2"
}
{
"slno" : NumberInt(3),
"name" : "Item 3"
}
I am receiving a request from angularJs frontend to update this collection to
{
"slno" : NumberInt(1),
"name" : "Item 3"
}
{
"slno" : NumberInt(2),
"name" : "Item 1"
}
{
"slno" : NumberInt(3),
"name" : "Item 2"
}
I am using Mongoose 5.0 ORM with Node 6.11 and express 4.15. Please help me find the best way to achieve this.
You basically want bulkWrite(), which can take the input array of objects and use it to make a "batch" of requests to update the matched documents.
Presuming the array of documents is being sent in req.body.updates, then you would have something like
const Model = require('../models/model');
router.post('/update', (req,res) => {
Model.bulkWrite(
req.body.updates.map(({ slno, name }) =>
({
updateOne: {
filter: { slno },
update: { $set: { name } }
}
})
)
})
.then(result => {
// maybe do something with the WriteResult
res.send("ok"); // or whatever response
})
.catch(e => {
// do something with any error
})
})
This sends a request given the input as:
bulkWrite([
{ updateOne: { filter: { slno: 1 }, update: { '$set': { name: 'Item 3' } } } },
{ updateOne: { filter: { slno: 2 }, update: { '$set': { name: 'Item 1' } } } },
{ updateOne: { filter: { slno: 3 }, update: { '$set': { name: 'Item 2' } } } } ]
)
Which efficiently performs all updates in a single request to the server with a single response.
Also see the core MongoDB documentation on bulkWrite(). That's the documentation for the mongo shell method, but all the options and syntax are exactly the same in most drivers and especially within all JavaScript based drivers.
As a full working demonstration of the method in use with mongoose:
const { Schema } = mongoose = require('mongoose');
const uri = 'mongodb://localhost/test';
mongoose.Promise = global.Promise;
mongoose.set('debug',true);
const testSchema = new Schema({
slno: Number,
name: String
});
const Test = mongoose.model('Test', testSchema);
const log = data => console.log(JSON.stringify(data, undefined, 2));
const data = [1,2,3].map(n => ({ slno: n, name: `Item ${n}` }));
const request = [[1,3],[2,1],[3,2]]
.map(([slno, n]) => ({ slno, name: `Item ${n}` }));
mongoose.connect(uri)
.then(conn =>
Promise.all(Object.keys(conn.models).map( k => conn.models[k].remove()))
)
.then(() => Test.insertMany(data))
.then(() => Test.bulkWrite(
request.map(({ slno, name }) =>
({ updateOne: { filter: { slno }, update: { $set: { name } } } })
)
))
.then(result => log(result))
.then(() => Test.find())
.then(data => log(data))
.catch(e => console.error(e))
.then(() => mongoose.disconnect());
Or for more modern environments with async/await:
const { Schema } = mongoose = require('mongoose');
const uri = 'mongodb://localhost/test';
mongoose.Promise = global.Promise;
mongoose.set('debug',true);
const testSchema = new Schema({
slno: Number,
name: String
});
const Test = mongoose.model('Test', testSchema);
const log = data => console.log(JSON.stringify(data, undefined, 2));
const data = [1,2,3].map(n => ({ slno: n, name: `Item ${n}` }));
const request = [[1,3],[2,1],[3,2]]
.map(([slno,n]) => ({ slno, name: `Item ${n}` }));
(async function() {
try {
const conn = await mongoose.connect(uri)
await Promise.all(Object.entries(conn.models).map(([k,m]) => m.remove()));
await Test.insertMany(data);
let result = await Test.bulkWrite(
request.map(({ slno, name }) =>
({ updateOne: { filter: { slno }, update: { $set: { name } } } })
)
);
log(result);
let current = await Test.find();
log(current);
mongoose.disconnect();
} catch(e) {
console.error(e)
} finally {
process.exit()
}
})()
Which loads the initial data and then updates, showing the response object ( serialized ) and the resulting items in the collection after the update is processed:
Mongoose: tests.remove({}, {})
Mongoose: tests.insertMany([ { _id: 5b1b89348f3c9e1cdb500699, slno: 1, name: 'Item 1', __v: 0 }, { _id: 5b1b89348f3c9e1cdb50069a, slno: 2, name: 'Item 2', __v: 0 }, { _id: 5b1b89348f3c9e1cdb50069b, slno: 3, name: 'Item 3', __v: 0 } ], {})
Mongoose: tests.bulkWrite([ { updateOne: { filter: { slno: 1 }, update: { '$set': { name: 'Item 3' } } } }, { updateOne: { filter: { slno: 2 }, update: { '$set': { name: 'Item 1' } } } }, { updateOne: { filter: { slno: 3 }, update: { '$set': { name: 'Item 2' } } } } ], {})
{
"ok": 1,
"writeErrors": [],
"writeConcernErrors": [],
"insertedIds": [],
"nInserted": 0,
"nUpserted": 0,
"nMatched": 3,
"nModified": 3,
"nRemoved": 0,
"upserted": [],
"lastOp": {
"ts": "6564991738253934601",
"t": 20
}
}
Mongoose: tests.find({}, { fields: {} })
[
{
"_id": "5b1b89348f3c9e1cdb500699",
"slno": 1,
"name": "Item 3",
"__v": 0
},
{
"_id": "5b1b89348f3c9e1cdb50069a",
"slno": 2,
"name": "Item 1",
"__v": 0
},
{
"_id": "5b1b89348f3c9e1cdb50069b",
"slno": 3,
"name": "Item 2",
"__v": 0
}
]
That's using syntax which is compatible with NodeJS v6.x
A small change in Neil Lunn's answer did the job.
const Model = require('../models/model');
router.post('/update', (req,res) => {
var tempArray=[];
req.body.updates.map(({slno,name}) => {
tempArray.push({
updateOne: {
filter: {slno},
update: {$set: {name}}
}
});
});
Model.bulkWrite(tempArray).then((result) => {
//Send resposne
}).catch((err) => {
// Handle error
});
Thanks to Neil Lunn.

Resources