I believe the issue revolves around the use of .save() and could possibly be associated with the object not having a .save() method.
/ This is the debugger output (thought I might as well clarify) /
Debugger listening on port 15454
Server started
events.js:141
throw er; // Unhandled 'error' event
^
TypeError: examBoard.save is not a function
at /home/ubuntu/workspace/tests/seeds.js:168:23
at Immediate.Model.$wrapCallback (/home/ubuntu/workspace/tests/node_modules/mongoose/lib/model.js:3336:16)
at Immediate._onImmediate (/home/ubuntu/workspace/tests/node_modules/mongoose/node_modules/mquery/lib/utils.js:137:16)
at processImmediate [as _immediateCallback] (timers.js:383:17)
Process exited with code: 1
Just to help anyone find the actual issue, I have used examBoad.save(); twice (once after the creation of all the examBoards and once close to the end of the program) and question.save(); once, I believe the problem to be with examBoard.save();
var mongoose = require("mongoose");
var examBoard = require("./models/examBoard");
var question = require("./models/question");
var user = require("./models/user");
function seedDB() {
examBoard.remove({}, function(err) {
if (err) {
console.log("Could not remove examBoard data" + err);
} else {
examBoard.insertMany({
name: "AQA",
modules: [{
name: "a",
topics: [{
name: "a1",
}, {
name: "a2",
}, {
name: "a3",
}]
}, {
name: "b",
topics: [{
name: "b1",
}, {
name: "b2",
}, {
name: "b3",
}]
}, {
name: "c",
topics: [{
name: "c1",
}, {
name: "c2",
}, {
name: "c3",
}]
}]
}, {
name: "OCR",
modules: [{
name: "a",
topics: [{
name: "a1",
}, {
name: "a2",
}, {
name: "a3",
}]
}, {
name: "b",
topics: [{
name: "b1",
}, {
name: "b2",
}, {
name: "b3",
}]
}, {
name: "c",
topics: [{
name: "c1",
}, {
name: "c2",
}, {
name: "c3",
}]
}]
}, {
name: "EXL",
modules: [{
name: "a",
topics: [{
name: "a1",
}, {
name: "a2",
}, {
name: "a3",
}]
}, {
name: "b",
topics: [{
name: "b1",
}, {
name: "b2",
}, {
name: "b3",
}]
}, {
name: "c",
topics: [{
name: "c1",
}, {
name: "c2",
}, {
name: "c3",
}]
}]
});
examBoard.save();
question.insertMany({
content: "<p>This is a question</p><br><img src='https://hd.unsplash.com/photo-1469537053566-3081fd1e0de2'><br><p>This is a bit after the image</p>",
mark: 6,
methods: [
[{
mark: 1,
content: "1a"
}, {
mark: 2,
content: "1b"
}, {
mark: 3,
content: "1c"
}],
[{
mark: 1,
content: "2a"
}, {
mark: 2,
content: "2b"
}, {
mark: 3,
content: "2c"
}],
[{
mark: 1,
content: "3a"
}, {
mark: 2,
content: "3b"
}, {
mark: 3,
content: "3c"
}]
]
}, {
content: "<p>This is a question</p><br><img src='https://hd.unsplash.com/photo-1465311440653-ba9b1d9b0f5b'><br><p>This is a bit after the image</p>",
mark: 9,
methods: [
[{
mark: 2,
content: "1a"
}, {
mark: 3,
content: "1b"
}, {
mark: 4,
content: "1c"
}],
[{
mark: 2,
content: "2a"
}, {
mark: 3,
content: "2b"
}, {
mark: 4,
content: "2c"
}],
[{
mark: 2,
content: "3a"
}, {
mark: 3,
content: "3b"
}, {
mark: 4,
content: "3c"
}]
]
}, {
content: "<p>This is a question</p><br><img src='https://hd.unsplash.com/photo-1467404899198-ccadbcd96b91'><br><p>This is a bit after the image</p>",
mark: 12,
methods: [
[{
mark: 3,
content: "1a"
}, {
mark: 4,
content: "1b"
}, {
mark: 5,
content: "1c"
}],
[{
mark: 3,
content: "2a"
}, {
mark: 4,
content: "2b"
}, {
mark: 5,
content: "2c"
}],
[{
mark: 3,
content: "3a"
}, {
mark: 4,
content: "3b"
}, {
mark: 5,
content: "3c"
}]
]
});
question.save();
examBoard[0].module[0].topic[0].push(question[0]);
examBoard[0].module[0].topic[0].push(question[1]);
examBoard[0].module[0].topic[0].push(question[2]);
examBoard[0].module[0].topic[1].push(question[0]);
examBoard[0].module[0].topic[1].push(question[1]);
examBoard[0].module[0].topic[1].push(question[2]);
examBoard[0].module[0].topic[2].push(question[0]);
examBoard[0].module[0].topic[2].push(question[1]);
examBoard[0].module[0].topic[2].push(question[2]);
examBoard[0].module[1].topic[0].push(question[0]);
examBoard[0].module[1].topic[0].push(question[1]);
examBoard[0].module[1].topic[0].push(question[2]);
examBoard[0].module[1].topic[1].push(question[0]);
examBoard[0].module[1].topic[1].push(question[1]);
examBoard[0].module[1].topic[1].push(question[2]);
examBoard[0].module[1].topic[2].push(question[0]);
examBoard[0].module[1].topic[2].push(question[1]);
examBoard[0].module[1].topic[2].push(question[2]);
examBoard[0].module[2].topic[0].push(question[0]);
examBoard[0].module[2].topic[0].push(question[1]);
examBoard[0].module[2].topic[0].push(question[2]);
examBoard[0].module[2].topic[1].push(question[0]);
examBoard[0].module[2].topic[1].push(question[1]);
examBoard[0].module[2].topic[1].push(question[2]);
examBoard[0].module[2].topic[2].push(question[0]);
examBoard[0].module[2].topic[2].push(question[1]);
examBoard[0].module[2].topic[2].push(question[2]);
examBoard[0].module[0].topic[0].push(question[0]);
examBoard[0].module[0].topic[0].push(question[1]);
examBoard[0].module[0].topic[0].push(question[2]);
examBoard[0].module[0].topic[1].push(question[0]);
examBoard[0].module[0].topic[1].push(question[1]);
examBoard[0].module[0].topic[1].push(question[2]);
examBoard[0].module[0].topic[2].push(question[0]);
examBoard[0].module[0].topic[2].push(question[1]);
examBoard[0].module[0].topic[2].push(question[2]);
examBoard[0].module[1].topic[0].push(question[0]);
examBoard[0].module[1].topic[0].push(question[1]);
examBoard[0].module[1].topic[0].push(question[2]);
examBoard[0].module[1].topic[1].push(question[0]);
examBoard[0].module[1].topic[1].push(question[1]);
examBoard[0].module[1].topic[1].push(question[2]);
examBoard[0].module[1].topic[2].push(question[0]);
examBoard[0].module[1].topic[2].push(question[1]);
examBoard[0].module[1].topic[2].push(question[2]);
examBoard[0].module[2].topic[0].push(question[0]);
examBoard[0].module[2].topic[0].push(question[1]);
examBoard[0].module[2].topic[0].push(question[2]);
examBoard[0].module[2].topic[1].push(question[0]);
examBoard[0].module[2].topic[1].push(question[1]);
examBoard[0].module[2].topic[1].push(question[2]);
examBoard[0].module[2].topic[2].push(question[0]);
examBoard[0].module[2].topic[2].push(question[1]);
examBoard[0].module[2].topic[2].push(question[2]);
examBoard[1].module[0].topic[0].push(question[0]);
examBoard[1].module[0].topic[0].push(question[1]);
examBoard[1].module[0].topic[0].push(question[2]);
examBoard[1].module[0].topic[1].push(question[0]);
examBoard[1].module[0].topic[1].push(question[1]);
examBoard[1].module[0].topic[1].push(question[2]);
examBoard[1].module[0].topic[2].push(question[0]);
examBoard[1].module[0].topic[2].push(question[1]);
examBoard[1].module[0].topic[2].push(question[2]);
examBoard[1].module[1].topic[0].push(question[0]);
examBoard[1].module[1].topic[0].push(question[1]);
examBoard[1].module[1].topic[0].push(question[2]);
examBoard[1].module[1].topic[1].push(question[0]);
examBoard[1].module[1].topic[1].push(question[1]);
examBoard[1].module[1].topic[1].push(question[2]);
examBoard[1].module[1].topic[2].push(question[0]);
examBoard[1].module[1].topic[2].push(question[1]);
examBoard[1].module[1].topic[2].push(question[2]);
examBoard[1].module[2].topic[0].push(question[0]);
examBoard[1].module[2].topic[0].push(question[1]);
examBoard[1].module[2].topic[0].push(question[2]);
examBoard[1].module[2].topic[1].push(question[0]);
examBoard[1].module[2].topic[1].push(question[1]);
examBoard[1].module[2].topic[1].push(question[2]);
examBoard[1].module[2].topic[2].push(question[0]);
examBoard[1].module[2].topic[2].push(question[1]);
examBoard[1].module[2].topic[2].push(question[2]);
examBoard[2].module[0].topic[0].push(question[0]);
examBoard[2].module[0].topic[0].push(question[1]);
examBoard[2].module[0].topic[0].push(question[2]);
examBoard[2].module[0].topic[1].push(question[0]);
examBoard[2].module[0].topic[1].push(question[1]);
examBoard[2].module[0].topic[1].push(question[2]);
examBoard[2].module[0].topic[2].push(question[0]);
examBoard[2].module[0].topic[2].push(question[1]);
examBoard[2].module[0].topic[2].push(question[2]);
examBoard[2].module[1].topic[0].push(question[0]);
examBoard[2].module[1].topic[0].push(question[1]);
examBoard[2].module[1].topic[0].push(question[2]);
examBoard[2].module[1].topic[1].push(question[0]);
examBoard[2].module[1].topic[1].push(question[1]);
examBoard[2].module[1].topic[1].push(question[2]);
examBoard[2].module[1].topic[2].push(question[0]);
examBoard[2].module[1].topic[2].push(question[1]);
examBoard[2].module[1].topic[2].push(question[2]);
examBoard[2].module[2].topic[0].push(question[0]);
examBoard[2].module[2].topic[0].push(question[1]);
examBoard[2].module[2].topic[0].push(question[2]);
examBoard[2].module[2].topic[1].push(question[0]);
examBoard[2].module[2].topic[1].push(question[1]);
examBoard[2].module[2].topic[1].push(question[2]);
examBoard[2].module[2].topic[2].push(question[0]);
examBoard[2].module[2].topic[2].push(question[1]);
examBoard[2].module[2].topic[2].push(question[2]);
examBoard.save();
console.log("Done seeding");
}
});
}
module.exports = seedDB;
The examBoard model
var mongoose = require("mongoose");
var topicSchema = new mongoose.Schema({
name: String,
questions: [{
type: mongoose.Schema.Types.ObjectId,
ref: "question"
}],
});
var moduleSchema = new mongoose.Schema({
name: String,
topics: [topicSchema]
});
var examBoardSchema = new mongoose.Schema({
name: String,
modules: [moduleSchema]
});
module.exports = mongoose.model("examBoard", examBoardSchema);
require implements a singleton pattern, in mongoose when require a model, it's necessary to instance a new object, something like this:
var exam = new examBoard(request.body); // request.body can to contain the values of the schema structure
exam.save();
The save method are only on the instance of an model, example
var examboard = new examBoard();
examboard.property = 'something';
examboard.save();
actually you already saving the objects when you say examBoard.insertMany();
Related
I am trying to create multiple arrays of objects with each keys inside the object.
How can I generate my expected output (shown below the initial array)?
Initial array:
[{
title: 'Linus tech tips',
name: 'Linus',
id: 'SA946',
},
{
title: 'Linus tech tips',
name: 'Colton',
id: 'SA947',
}
];
Expected output:
[{
text: 'Linus tech tips',
}, {
text: 'Linus',
}, {
text: 'SA946',
}, ],
[{
text: 'Linus tech tips',
}, {
text: 'Colton',
}, {
text: 'SA947',
}, ],
You can use array.map to achieve that. Please have a look:
const initial = [
{
title: 'Linus tech tips',
name: 'Linus',
id: 'SA946',
},
{
title: 'Linus tech tips',
name: 'Colton',
id: 'SA947',
},
];
const expected = initial.map(
(item) => Object.values(item).map(
(itemValue) => ({ text: itemValue }),
),
);
console.log(expected);
You need to iterate over the keys, then flatten the array.
[{
title: 'Linus tech tips',
name: 'Linus',
id: 'SA946',
},
{
title: 'Linus tech tips',
name: 'Colton',
id: 'SA947',
}].map(
item => {
return Object.keys(item).map(
key => {
return {text: item[key]}
}
)
}
).flat()
[
{
"text": "Linus tech tips"
},
{
"text": "Linus"
},
{
"text": "SA946"
},
{
"text": "Linus tech tips"
},
{
"text": "Colton"
},
{
"text": "SA947"
}
]
Or, if you want to have the items separated, do not use flat() at the end:
[
[
{
"text": "Linus tech tips"
},
{
"text": "Linus"
},
{
"text": "SA946"
}
],
[
{
"text": "Linus tech tips"
},
{
"text": "Colton"
},
{
"text": "SA947"
}
]
]
I have a javascript object as follows :
let hogwartsHeirarchy = {
Headmaster: [
{
name: "Professor Dumbledore",
key: 1,
Headmistress: [
{
name: "Minerva McGonagall",
key: 2,
StandByProfessor: [
{
name: "Rubeus Hagrid",
subject: "Potions Master",
key: 3,
Professor: [
{ name: "Horace Slughorn", key: 4 },
{ name: "Severus Snape", key: 4 },
],
},
{
name: "Alastor Moody",
subject: "Defense Against the Dark Arts",
key: 3,
Professor: [
{ name: "Remus Lupin", key: 4 },
{ name: "Gilderoy Lockhart", key: 4 },
],
},
],
},
],
},
],
};
I want to print/get each of the node value [headmaster, headmastress,..] and their corresponding child values. I tried various methods like looping through the array using a for loop, recurse etc, but unfortunately I am not able to get any value out of the nodes. Please help.
e.g : I used this :
printArray(hogwartsHeirarchy);
function printArray(arr){
for(var i = 0; i < arr.length; i++){
if(arr[i] instanceof Array){
console.log("true: ");
console.log("intermediate one : ",arr[i]);
printArray(arr[i]);
}else{
console.log("final one : ",arr[i]);
}
}
}
The values can be shown in this format:
Headmaster - name : Professor Dumbledore, key : 1
.
.
StandByProfessor - name : Robeus Hagrid, subject : Potion Master, key : 3
StandByProfessor - name : Alastor Moody, subject : Defence against the dark arts, key : 3
.
.
Professor - ...
Professor - ...
Professor - ...
Professor - ...
I would suggest restructuring so that the subordinates are always accessed with the same key, and thus can be visited very simply. I also made it so every node is a person, there's no object at the top that isn't a person. I left the variable name, but it now refers to Dumbledore directly.
let hogwartsHeirarchy =
{
name: "Professor Dumbledore",
role: "Headmaster",
key: 1,
subordinates: [
{
name: "Minerva McGonagall",
role: "Headmistress",
key: 2,
subordinates: [
{
name: "Rubeus Hagrid",
role: "StandByProfessor",
subject: "Potions Master",
key: 3,
subordinates: [
{ name: "Horace Slughorn", key: 4, role: "Professor" },
{ name: "Severus Snape", key: 4, role: "Professor" },
],
},
{
name: "Alastor Moody",
role: "StandByProfessor",
subject: "Defense Against the Dark Arts",
key: 3,
subordinates: [
{ name: "Remus Lupin", key: 4, role: "Professor" },
{ name: "Gilderoy Lockhart", key: 4, role: "Professor" },
],
},
],
},
],
};
function visitStaff(staffMember) {
if (staffMember.subordinates) {
for (const subordinate of staffMember.subordinates) {
visitStaff(subordinate);
}
}
console.log("Staff member:", staffMember);
}
visitStaff(hogwartsHeirarchy);
When setting up a data structure, it's important to think about how it will be accessed, and what are its defining parts. In this case, there are people, which are the nodes, and (subordinate) relationships, which are the edges of the graph.
In your original code, you had an object { Headmaster: [...] } — what does it represent? is it a person? no; is it a relationship? kind of, but no. It defines something about Dumbledoor, that he's the Headmaster, but not who or what he's the Headmaster of. So it's really just describing the role/job title of Dumbledoor, so it makes more sense as a property of the person. It's redundant as an object.
It helps to align your objects so they all represent something. You should be able to describe what each object and array is.
Given the data structure:
a) I assume that there will be only one array in each type of "title", and
b) that array will contain a list of objects of a similar structure as it's parent
It's possible ...
to use for..of in order to
iterate through each key on an object, and add them to a string. Because there are arrays that contains objects,
I can loop through them, and
do a recursive loop, by having the method calling itself.
const hogwartsHierarchy = { Headmaster: [{ name: "Professor Dumbledore", key: 1, Headmistress: [{ name: "Minerva McGonagall", key: 2, StandByProfessor: [{ name: "Rubeus Hagrid", subject: "Potions Master", key: 3, Professor: [{ name: "Horace Slughorn", key: 4 }, { name: "Severus Snape", key: 4 }] }, { name: "Alastor Moody", subject: "Defense Against the Dark Arts", key: 3, Professor: [{ name: "Remus Lupin", key: 4 }, { name: "Gilderoy Lockhart", key: 4 }] }] }] }] };
function printAllWithChilds(obj, prevProp) {
let listItem = (prevProp) ? ' -- ' + prevProp : '';
for (const property in obj) { // 1
if (obj[property] instanceof Array) {
obj[property].forEach((child_obj) => { // 3
listItem += printAllWithChilds(child_obj, property); // 4
});
} else {
listItem += `, ${property}: ${obj[property]}`; // 2
}
}
return listItem;
}
let listStr = printAllWithChilds(hogwartsHierarchy);
console.log(listStr);
I would honestly split up hogwartsHierarchy into smaller bits, following a kind of database structure, where primary_key is unique for each individual. These arrays doesn't make much sense, until you look at the variable professors and how their respectively belongs_to key corresponds to the standbyprofessors, where you can see that "Horace Slughorn" belongs to "Rubeus Hagrid".
const headermaster = {
name: "Professor Dumbledore",
primary_key: 1
};
const headmistress = {
name: "Minerva McGonagall",
primary_key: 2,
belongs_to: 1
};
const standbyprofessors = [{
name: "Rubeus Hagrid",
subject: "Potions Master",
primary_key: 3,
belongs_to: 2
},
{
name: "Alastor Moody",
subject: "Defense Against the Dark Arts",
primary_key: 4,
belongs_to: 2
}
];
const professors = [{
name: "Horace Slughorn",
primary_key: 5,
belongs_to: 3
},
{
name: "Severus Snape",
primary_key: 6,
belongs_to: 3
},
{
name: "Remus Lupin",
primary_key: 7,
belongs_to: 4
},
{
name: "Gilderoy Lockhart",
primary_key: 8,
belongs_to: 4
},
];
You could remove known keys from the object and get the type hierarchy then iterate the property and return the tupel of type, name, subject and key only if type exists.
const
getValues = (object, type) => [
...(type ? [`${type} - name : ${object.name}, ${object.subject ? `subject : ${object.subject}, ` : ''}key : ${object.key}`] : []),
...Object
.keys(object)
.filter(k => !['name', 'subject', 'key'].includes(k))
.flatMap(k => object[k].flatMap(o => getValues(o, k)))
],
hogwartsHierarchy = { Headmaster: [{ name: "Professor Dumbledore", key: 1, Headmistress: [{ name: "Minerva McGonagall", key: 2, StandByProfessor: [{ name: "Rubeus Hagrid", subject: "Potions Master", key: 3, Professor: [{ name: "Horace Slughorn", key: 4 }, { name: "Severus Snape", key: 4 }] }, { name: "Alastor Moody", subject: "Defense Against the Dark Arts", key: 3, Professor: [{ name: "Remus Lupin", key: 4 }, { name: "Gilderoy Lockhart", key: 4 }] }] }] }] };
console.log(getValues(hogwartsHierarchy));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Based on a 1j01 object model:
const hogwartsHeirarchy =
{ name: "Professor Dumbledore", role: "Headmaster", key: 1,
subordinates: [{ name: "Minerva McGonagall", role: "Headmistress", key: 2,
subordinates: [
{ name: "Rubeus Hagrid", role: "StandByProfessor", subject: "Potions Master", key: 3,
subordinates: [
{ name: "Horace Slughorn", key: 4, role: "Professor" },
{ name: "Severus Snape", key: 4, role: "Professor" }]},
{ name: "Alastor Moody", role: "StandByProfessor", subject: "Defense Against the Dark Arts", key: 3,
subordinates: [
{ name: "Remus Lupin", key: 4, role: "Professor" },
{ name: "Gilderoy Lockhart", key: 4, role: "Professor" }]}]}]};
const visitStaff = (staffMember) => {
const iter = (obj) => {
const { name, role, key, subordinates } = obj;
const subject = obj.subject ? `, subject : ${obj.subject}` : '';
const line = `${role} - name : ${name}${subject}, key : ${key}`;
const sublines = (Array.isArray(subordinates)) ? subordinates.flatMap(iter) : [];
return [line, ...sublines];
}
return iter(staffMember).join('\n');
}
console.log(visitStaff(hogwartsHeirarchy));
.as-console-wrapper { max-height: 100% !important; top: 0; }
i have this array, i want to merge all elements inside the objects in the nested arrays and remove the duplicates..
the array is the output of mongo db populate so answers from there or just js will be amazing :)
"visitors": [
[
{
"name": "matan",
"id": "61793e6a0e08cdcaf213c0b1"
},
{
"name": "shani",
"id": "61793e910e08cdcaf213c0b5"
}
],
[
{
"name": "david",
"id": "6179869cb4944c6b19b05a23"
},
{
"name": "orit",
"id": "617986e535fdf4942ef659bd"
}
],
[
{
"name": "david",
"id": "6179869cb4944c6b19b05a23"
},
{
"name": "orit",
"id": "617986e535fdf4942ef659bd"
}
]
]
would like this output -
"visitors": [
{
"name": "matan",
"id": "61793e6a0e08cdcaf213c0b1"
},
{
"name": "shani",
"id": "61793e910e08cdcaf213c0b5"
},
{
"name": "david",
"id": "6179869cb4944c6b19b05a23"
},
{
"name": "orit",
"id": "617986e535fdf4942ef659bd"
},
]
these are my collections
i need to get all visitors on one solar system,
so > solars > planets > visitors
const solarsModel = new Schema({
planets: [ { type: Schema.Types.ObjectId ,ref:'planet'} ],
starName: { type: String, required: true, default: "" }
})
const planetModel = new Schema({
planetName: { type: String, required: true, default: "" },
system:{type: Schema.Types.ObjectId, ref: 'solar'},
visitors: [{ type: Schema.Types.ObjectId , ref: 'visitor'}]
})
const visitorModel = new Schema({
visitorName:{ type: String, required: true, default: "" },
homePlanet: {type: Schema.Types.ObjectId, ref:"planet" },
visitedPlanets: [{ type: Schema.Types.ObjectId, ref:"planet" }]
})
this is what i did to achieve a result would love to use Aggregate..
const response = await solarModel
.findById({ _id: data.id })
.select({ starName: 1, _id: 0 })
.populate({
path: "planets",
select: { visitors: 1, _id: 0 },
populate: {
path: "visitors",
select: "visitorName",
},
})
.exec();
solved with this
exports.findVisitorSystemHandler = async (data) => {
const systemName = await solarModel.findById({ _id: data.id });
const response = await planetModel.aggregate([
{ $match: { system: makeObjectId(data.id) } },
{
$lookup: {
from: "visitors",
localField: "visitors",
foreignField: "_id",
as: "solarVisitors",
},
},
{
$project: {
solarVisitors: {
visitedPlanets: 0,
homePlanet: 0,
__v: 0,
},
},
},
{ $unwind: "$solarVisitors" },
{
$group: {
_id: null,
system: { $addToSet: systemName.starName },
solarVisitors: {
$addToSet: {
id: "$solarVisitors._id",
name: "$solarVisitors.visitorName",
},
},
},
},
{ $unwind: "$system" },
{
$project: {
_id: 0,
},
},
]);
return response;
};
You can use aggregate() like this:
$unwind twice due to nested array
$group using $addToSet to not get duplicates.
db.collection.aggregate([
{
"$unwind": "$visitors"
},
{
"$unwind": "$visitors"
},
{
"$group": {
"_id": null,
"visitors": {
"$addToSet": {
"id": "$visitors.id",
"name": "$visitors.name"
}
}
}
}
])
Example here
(1) Flatten the array of arrays
visitors = visitors.flat();
Which gives us this:
[
{ name: 'matan', id: '61793e6a0e08cdcaf213c0b1' },
{ name: 'shani', id: '61793e910e08cdcaf213c0b5' },
{ name: 'david', id: '6179869cb4944c6b19b05a23' },
{ name: 'orit', id: '617986e535fdf4942ef659bd' },
{ name: 'david', id: '6179869cb4944c6b19b05a23' },
{ name: 'orit', id: '617986e535fdf4942ef659bd' }
]
(2) Get unique ids
let uniqueIds= [...new Set(visitors.map(v => v.id)]
Which gives us this:
[
'61793e6a0e08cdcaf213c0b1',
'61793e910e08cdcaf213c0b5',
'6179869cb4944c6b19b05a23',
'617986e535fdf4942ef659bd'
]
(3) Get new list of visitors based only on uniqueIds
visitors = uniqueIds.map(id => {
let name = visitors.find(v => v.id === id).name;
return {
id,
name
}
});
Which gives us this:
[
{ name: 'matan', id: '61793e6a0e08cdcaf213c0b1' },
{ name: 'shani', id: '61793e910e08cdcaf213c0b5' },
{ name: 'david', id: '6179869cb4944c6b19b05a23' },
{ name: 'orit', id: '617986e535fdf4942ef659bd' },
]
Query
reduce with concat to flatten
union with an empty array,just to remove duplicates
if you have other fields except visitors they are not affected
PlayMongo
aggregate(
[{"$set":
{"visitors":
{"$setUnion":
[{"$reduce":
{"input": "$visitors",
"initialValue": [],
"in": {"$concatArrays": ["$$value", "$$this"]}}},
[]]}}}])
Results
[{
"visitors": [
{
"name": "david",
"id": "6179869cb4944c6b19b05a23"
},
{
"name": "matan",
"id": "61793e6a0e08cdcaf213c0b1"
},
{
"name": "orit",
"id": "617986e535fdf4942ef659bd"
},
{
"name": "shani",
"id": "61793e910e08cdcaf213c0b5"
}
]
}]
So I am looking through the Prisma docs and I come across an example to create a relational query. This query inserts a new post and assigns it an author with an existing category.
const assignCategories = await prisma.post.create({
data: {
title: 'How to be Bob',
categories: {
create: [
{
assignedBy: 'Bob',
assignedAt: new Date(),
category: {
connect: {
id: 9,
},
},
},
{
assignedBy: 'Bob',
assignedAt: new Date(),
category: {
connect: {
id: 22,
},
},
},
],
},
},
})
I can understand what this query does but I don't understand how to implement this on a backend with the incoming request body.
Suppose I have this request body
{
"title": "how to be bob",
"categories": [
{
"assignedby": "bob",
"category": {
"id": 9
}
},
{
"assignedby": "bob",
"category": {
"id": 22
}
}
]
}
How do I transform this request body to the data object in the first codeblock?
I got it. It was in my face all along. Just use .map to map through the categories
const data = {
title: 'how to be bob',
categories: [
{
assignedby: 'bob',
category: {
id: 9,
},
},
{
assignedby: 'bob',
category: {
id: 22,
},
},
],
};
const mappedData = {
title: data.title,
categories: {
create: data.categories.map((i) => ({
assignedBy: i.assignedby,
assignedAt: new Date(),
category: {
connect: {
id: i.category.id,
},
},
})),
},
};
console.log(mappedData);
which logs this
"title": "how to be bob",
"categories": {
"create": [
{
"assignedBy": "bob",
"assignedAt": "2021-10-24T12:10:00.397Z",
"category": {
"connect": {
"id": 9
}
}
},
{
"assignedBy": "bob",
"assignedAt": "2021-10-24T12:10:00.397Z",
"category": {
"connect": {
"id": 22
}
}
}
]
}
}
Just what we exactly need.
I have a JSON structure similar to this:
[
{
cells: [
{ id: "1", cellType: 3, widget: { id: 1, description: "myDesc"} },
{ id: "2", cellType: 4, widget: { id: 2, description: "myDesc2"} }
]
},
{
cells: [
{ id: "3", cellType: 5, widget: { id: 3, description: "myDesc3"} }
]
},
...
]
How do I get the value of every widget into a separate array using EcmaScript (or anything that's available in Angular 2+), and without using a library (including JQuery)? I need a final array like this:
[
{
id: 1,
description: "myDesc"
},
{
id: 2,
description: "myDesc2"
},
...
]
Update
(and thanks to #Felix Kling for the 1st part) - I found I can get all of the widgets with this:
JSON.parse(json)[0].forEach( c => c.cells.forEach( c2 => console.log(c2.widget)));
You can use .map() with .reduce()
let input = [
{
cells: [
{ id: "1", cellType: 3, widget: { id: 1, description: "myDesc"} },
{ id: "1", cellType: 4, widget: { id: 2, description: "myDesc2"} }
]
},
{
cells: [
{ id: "3", cellType: 5, widget: { id: 3, description: "myDesc3"} }
]
},
];
let result = input.reduce((result, current) => {
return result.concat(current.cells.map(x => x.widget));
}, [])
console.log(result);
You can use .map() and .concat() to get the desired result:
let data = [{
cells: [
{ id: "1", cellType: 3, widget: { id: 1, description: "myDesc"} },
{ id: "1", cellType: 4, widget: { id: 2, description: "myDesc2"} }
]}, {
cells: [
{ id: "3", cellType: 5, widget: { id: 3, description: "myDesc3"} }
]
}];
let result = [].concat(...data.map(({cells}) => cells.map(({widget}) => widget)));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }