I need to set an array for objects to firestore but only the first index of urls is getting stored. Any help in the right direction would be helpful thanks.
Code:
const object = [
{
user: 'mike',
userName: 'Mike nick',
Urls:[
{comment: "BBBBB", imageUrl: "url1"},
{comment: "BBBJvuyiu", imageUrl: "url2"},
{comment: "AAAAA", imageUrl: "url3"},
],
date: 'March 20th'
}
]
firestoreRef
.collection('users')
.doc(userId)
.collection('images')
.doc('customers')
.collection('customerExperience')
.doc(userId)
.set(object, { merge: true })
need this structure as user may continue to add more data:
it looks like this when i upload the object.
Your const object is actually an Array, when it should be an Object (that is not an Array).
The following should work:
const object = {
user: 'mike',
userName: 'Mike nick',
urls: [
{ comment: 'BBBBB', imageUrl: 'url1' },
{ comment: 'BBBJvuyiu', imageUrl: 'url2' },
{ comment: 'AAAAA', imageUrl: 'url3' }
],
date: 'March 20th'
};
Note the difference with your object:
const object = [
{
.....
}
]
UPDATE following your comment:
If you want to have it saved exactly the way you show in your updated question, do as follows. I am not sure however that this is the best way to save your data: as a matter of fact you are not creating an array but several fields of type "map" with the following names: 0, 1, etc.
One of the main (negative) side effect is that you will need to know all the fields names upfront in order to read them, while with a "genuine" Array field, you can loop over its values.
const object = {
0: {
user: 'mike1',
userName: 'Mike nick',
urls: [
{ comment: 'BBBBB', imageUrl: 'url1' },
{ comment: 'BBBJvuyiu', imageUrl: 'url2' },
{ comment: 'AAAAA', imageUrl: 'url3' }
],
date: 'March 20th'
},
1: {
user: 'mike2',
userName: 'Mike nick',
urls: [
{ comment: 'BBBBB', imageUrl: 'url1' },
{ comment: 'BBBJvuyiu', imageUrl: 'url2' },
{ comment: 'AAAAA', imageUrl: 'url3' }
],
date: 'March 20th'
}
};
From the Official Documentation, here's the sample code for the different data types:
let data = {
stringExample: 'Hello, World!',
booleanExample: true,
numberExample: 3.14159265,
dateExample: admin.firestore.Timestamp.fromDate(new Date('December 10, 1815')),
arrayExample: [5, true, 'hello'],
nullExample: null,
objectExample: {
a: 5,
b: true
}
};
You will need the following to create an object that contains an array of objects
let object = {
user: 'mike',
userName: 'Mike nick',
urls: {
[{comment: 'BBBBB', imageUrl: 'url1'},
{comment: 'BBBJvuyiu', imageUrl: 'url2'},
{comment: 'AAAAA', imageUrl: 'url3'}]
},
date: 'March 20th'
};
Let me know if this works for you.
Related
I have a prisma query that returns users on a pivot table CommunityMember. The pivot table associates to the table User. As a result, my queries into the User table do not place the object user on top of the replies. I have a lot of functions designed to run with the user object on top so I am trying to figure out how to map user into my returns so the functions can run correctly. I've tried a lot of combinations of map and have had no luck. Do you all have any ideas?
Here is my prisma query:
members = await prisma.user.findMany({
select: {
id: true,
username: true,
name: true,
bio: true,
avatar: true,
},
skip: 10 * Number(page),
take: 10,
});
It gives a result like
members:
[{id: 2, username: 'man}, {id: 3, username: 'dan'}]
I want it to look like: members:
members:
[{user: {id: 2, username: 'man'}}, {user: {id: 3. username: 'dan'}}]
If I run members[0].user I should get the data inside. It seems like a simple map function, but I have not been able to get it to work.
Another example of what I get, but do not want.
members: [
{
id: 2,
username: 'man',
name: 'A Man',
bio: 'A man.',
avatar: [Object]
},
{
id: 3,
username: 'dude',
name: 'Dude',
bio: "Dude is a #1 developer.",
avatar: [Object]
},
This is what I want.
members: [
{
//Notice the user object on top of each entry
user: {
id: 2,
username: 'man',
name: 'A Man',
bio: 'Man.',
avatar: [Object]
}
},
{
user: {
id: 3,
username: 'dude',
name: 'Dude',
bio: "Dudes a #1 developer.",
avatar: [Object]
}
},
]
Not sure I got the whole picture but wouldn't this do?
const members = [
{
id: 2,
username: 'man',
name: 'A Man',
bio: 'A man.',
avatar: {}
},
{
id: 3,
username: 'dude',
name: 'Dude',
bio: "Dude is a #1 developer.",
avatar: {}
}
].map(member => ({user: member}))
if your object looks like:
obj = {members: [{...}, ..]}
then an Array.map will solve the problem:
const userMembers = obj.members.map((member) => ({user: member});
obj.members = userMembers;
In a project I'm working on, I need to merge 2 arrays of objects and as a result one new array of objects containing the merged key/values where two Ids match.
To give an example I created the following snippet but is not fully correct on what I want to achieve. More details after the snippet
const users = [{
id: 'Ae7uWu7LjwoEgVqzFU5xc',
firstName: 'Carl',
lastName: 'Jones'
},
{
id: 't2wzj8dh4r-qw1_SW-IOE',
firstName: 'Chloe',
lastName: 'Kearney'
},
{
id: '50Zwvw37OejbQBG7csZWJ',
firstName: 'Gemma',
lastName: 'Sloan'
},
{
id: 'NpcXdEKqfzhVCZOJ1dKuw',
firstName: 'Dario',
lastName: 'Angelini'
},
{
id: 'e95ZG9IfV442HdJp-CaBL',
firstName: 'Mindy',
lastName: 'Schreiber'
},
{
id: 'eAMv8AbynYRkdBPE5Scm2',
firstName: 'Xdax',
lastName: 'Rufq'
},
{
id: 'egMXnFvoMM7f4in3Se4Ui',
firstName: 'Mtajx',
lastName: 'Plde'
},
{
id: '6kbPT-HC5-szACuJ85I6r',
firstName: 'Zsofi',
lastName: 'Toke'
}
]
const comments = [{
content: 'Patient follow up call scheduled for 11Nov2021 at 8am',
stage: 'AT_CALLCENTER',
userId: 't2wzj8dh4r-qw1_SW-IOE',
createdAt: '2021-10-29T11:41:11.780Z'
},
{
content: 'Patient confirmed GP referral on [date]',
stage: 'AT_CALLCENTER',
userId: 't2wzj8dh4r-qw1_SW-IOE',
createdAt: '2021-10-29T11:41:42.237Z'
},
{
content: 'Candidate called on [date] and visit scheduled for [date] ',
stage: 'AT_SITE',
userId: 't2wzj8dh4r-qw1_SW-IOE',
createdAt: '2021-10-29T11:43:42.140Z'
},
{
content: 'Candidate test result was positive for Pompe disease on [date]',
stage: 'AT_SITE',
userId: 't2wzj8dh4r-qw1_SW-IOE',
createdAt: '2021-10-29T11:45:21.716Z'
}
]
const result = users.map(t1 => ({
...t1,
content: comments.filter(t2 => t2.userId === t1.id).map(t1 => t1.content),
created: comments.filter(t2 => t2.userId === t1.id).map(t1 => t1.createdAt),
}));
console.log(result)
The result I was able to get from that try was an array of objects but the comments are represented as an array inside the user object itself as for the createdAt
this is an example of what I'm getting now
[{
"id": "t2wzj8dh4r-qw1_SW-IOE",
"firstName": "Chloe",
"lastName": "Kearney",
"content": [
"Patient follow up call scheduled for 11Nov2021 at 8am",
"Patient confirmed GP referral on [date]",
"Candidate called on [date] and visit scheduled for [date] ",
"Candidate test result was positive for Pompe disease on [date]"
],
"created": [
"2021-10-29T11:41:11.780Z",
"2021-10-29T11:41:42.237Z",
"2021-10-29T11:43:42.140Z",
"2021-10-29T11:45:21.716Z"
]
},]
What I would like to get is the way around, I mean I want the comments to include the
firstName and lastName of the user when the comments.userId is equal to the users.id
Example of the goal I want to achieve
consider the 2 objects below
comments = [{
content: 'Patient follow up call scheduled for 11Nov2021 at 8am',
stage: 'AT_CALLCENTER',
userId: 't2wzj8dh4r-qw1_SW-IOE',
createdAt: '2021-10-29T11:41:11.780Z'
},
{
content: 'Patient confirmed GP referral on [date]',
stage: 'AT_CALLCENTER',
userId: 't2wzj8dh4r-qw1_SW-IOE',
createdAt: '2021-10-29T11:41:42.237Z'
}, { ...some other comments...}]
users = [
{
id: 't2wzj8dh4r-qw1_SW-IOE',
firstName: 'Chloe',
lastName: 'Kearney'
},
{ ...some other users... }]
The result I'm seeking after the 2 objects are merged is as follows
res = [
{
firstName: 'Chloe',
lastName: 'Kearney',
content: 'Patient follow up call scheduled for 11Nov2021 at 8am',
stage: 'AT_CALLCENTER',
userId: 't2wzj8dh4r-qw1_SW-IOE',
createdAt: '2021-10-29T11:41:11.780Z'
},
{
firstName: 'Chloe',
lastName: 'Kearney',
content: 'Patient confirmed GP referral on [date]',
stage: 'AT_CALLCENTER',
userId: 't2wzj8dh4r-qw1_SW-IOE',
createdAt: '2021-10-29T11:41:42.237Z'
}
]
As above I'm adding the first and last name of the user with the comments where there is an Ids match, so they are together after the merging.
I'm looking to understand a good way of doing this
const comments = [{
content: 'Patient follow up call scheduled for 11Nov2021 at 8am',
stage: 'AT_CALLCENTER',
userId: 't2wzj8dh4r-qw1_SW-IOE',
createdAt: '2021-10-29T11:41:11.780Z'
},{
content: 'Patient confirmed GP referral on [date]',
stage: 'AT_CALLCENTER',
userId: 't2wzj8dh4r-qw1_SW-IOE',
createdAt: '2021-10-29T11:41:42.237Z'
}];
const users = [{
id: 't2wzj8dh4r-qw1_SW-IOE',
firstName: 'Chloe',
lastName: 'Kearney'
}];
console.log(
comments.map(comment => {
const {id, ...user} = users.find(({id}) => id===comment.userId);
return ({...user, ...comment});
}));
My issue today is with MongoDB and mongoose in javascript. So first off I have this schema:
var playerModel = new Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "Users",
},
class: {
type: String,
required: true,
},
level: {
type: Number,
default: 1,
},
spells: {
type: [String],
default: ["", "", "", "", ""],
},
inventory: [], <- IMPORTANT
toolbelt: {
axe: [{}],
pickaxe: [{}],
fishingrod: [{}],
hammer: [{}],
saw: [{}],
sewingkit: [{}],
knife: [{}],
gemkit: [{}],
food: [{}],
potion: [{}],
},
gear: {
weapon: [{}],
head: [{}],
chest: [{}],
gloves: [{}],
legs: [{}],
shoes: [{}],
earrings: [{}],
ring: [{}],
necklace: [{}],
},
gold: {
type: Number,
default: 0,
},
bagSize: {
type: Number,
default: 20,
},
skills: {
type: [userSkills],
default: defaultSkills,
},
});
and my problem is with inventory: [].
In my code I manually push items in my array which save properly in the database, but whenever I wanna modify a field of one of my array object, it won't update it like a qty for example:
player.inventory[i].qty += 1; //Where player is my model containing my inventory
...
player.save()
.then((doc) => console.log("DOC", doc))
.catch((err) => console.log("ERR", err));
and the doc returned look something like this:
...
inventory: [
{
_id: 626a1468cdbeced19102942d,
slug: 'crude_campfire',
qty: 1,
charges: 19,
efficiency: -0.2
},
{ _id: 626a14e7530afad2c5c1894c, slug: 'wheat', qty: 1 },
{ _id: 626a14f1530afad2c5c1894d, slug: 'carrot', qty: 1 },
{ _id: 626a150f530afad2c5c1894e, slug: 'potato', qty: 1 },
{ _id: 626a155b530afad2c5c1894f, slug: 'red_bream', qty: 1 },
{ _id: 626a15b5530afad2c5c18950, slug: 'bone', qty: 1 },
{ _id: 626a15c9530afad2c5c18951, slug: 'clam_shell', qty: 1 },
{ _id: 626a15d5530afad2c5c18952, slug: 'stone', qty: 8 },
{ _id: 626a15df530afad2c5c18953, slug: 'taeroot', qty: 1 },
{ _id: 626a15e9530afad2c5c18954, slug: 'shiny_pendant', qty: 1 },
{ _id: 626a15fd530afad2c5c18955, slug: 'sickleweed', qty: 1 },
{ _id: 626a1625530afad2c5c18956, slug: 'ceruleaf', qty: 1 },
{ _id: 626a1dba272403ea21fb71ef, slug: 'stone', qty: 1 },
{ _id: 626a1e4030a144f8179789e0, slug: 'birch_log', qty: 22 }, <- IMPORTANT
{ _id: 626a1e72372733f90cfdc003, slug: 'tree_twig', qty: 2 },
{ _id: 626a1e9a372733f90cfdc004, slug: 'honey', qty: 2 }
],
...
where you can see that my birch_log qty is now at 22. But whenever I go check in the database,
I don't know what's going on, and I'm kind of tired right, so I'll go to bed hoping someone can save me tomorrow :)
Thanks and have a good night ! :)
To update the object having {slug: birch_log}, you can use the following query:
player.update( {user : 123456 , inventory.slug : "birch_log" } ,
{$inc : {"inventory.$.qty" : 1} });
instead of using save() with promise, you can use update() query with async await. It will be short and clean code.
This answer fixed my problem
Since i'm using an "anonymous" array or whatever, mongoose doesn't know what changes to track in it so I need to tell it that it's been modified !
I have the following schema:
const MenuSchema = new mongoose.Schema({
name: String,
type: String,
children: [{ type: ObjectId, ref: 'Menu' }],
});
And the following query:
const res = await Menu.aggregate([
{ $graphLookup: { from: "menus", startWith: "$children", connectToField: "children", connectFromField: "_id", as: "menus" }}
]);
As you can see, the menu schema is a self-referential data structure, children stores references to other instances of the same entity, with a 'type' field to differentiate the levels. I'm attempting to find and populate documents for each array of children (which are just BSON IDs) and return the results.
The above example seems to get most of the way there, however when I access one of the populated menus, it has a list of all the populated children in a flattened array, it doesn't retain the relationship structure.
For example, if I print out res, I get:
[ {
_id: 5f1212d053e5494bb45f18f3,
children: [ 5f1212d053e5494bb45f18f1 ],
name: 'Vodka',
type: 'Item',
__v: 0,
menus: [ [Object], [Object], [Object], [Object] ]
},
{
_id: 5f1212d053e5494bb45f18f4,
children: [ 5f1212d053e5494bb45f18f3, 5f1212d053e5494bb45f18f2 ],
name: 'Drinks',
type: 'Category',
__v: 0,
menus: [ [Object], [Object] ]
},
{
_id: 5f1212d053e5494bb45f18f5,
children: [ 5f1212d053e5494bb45f18f4 ],
name: 'Main Menu',
type: 'Menu',
__v: 0,
menus: [ [Object] ]
}
]
But when I print out res[1].menus, I get:
[
{
_id: 5f1212d053e5494bb45f18f3,
children: [ 5f1212d053e5494bb45f18f1 ],
name: 'Vodka',
type: 'Item',
__v: 0
},
{
_id: 5f1212d053e5494bb45f18f1,
children: [ 5f1212d053e5494bb45f18f0 ],
name: 'Double',
type: 'Variant',
__v: 0
},
{
_id: 5f1212d053e5494bb45f18f4,
children: [ 5f1212d053e5494bb45f18f3, 5f1212d053e5494bb45f18f2 ],
name: 'Drinks',
type: 'Category',
__v: 0
}
]
Which is all of the children in a flat array.
Is $graphLookup the correct approach, or am I just using it wrong?
I don't know if you are still looking for the answer for this, but if you use mongoose you can take advantage of the populate feature and use it as a middleware
Here's an example:
Let's say I want a list of people and their friends, and their friends-friends, etc. The result should look like this:
[
{
_id: "abc123",
name: "John Doe",
friends: [
{
_id: "efg456",
name: "Foo bar",
friends: [
{
_id: "hij789",
name: "Jane Doe",
friends: [more friends...]
}
]
}
]
]
In the db they are stored like this
{_id: "abc123", name: "John Doe", friends: ["efg456"]}
{_id: "efg456", name: "Foo bar", friends: ["hij789"]}
{_id: "hij789", name: "Jane Doe", friends: [more friends...]}
Your schema and middleware would be:
const Person = new Schema<Folder>({
name: {type: String, required: true},
friends: [{type: Schema.Types.ObjectId, ref: "person"}],
}, {timestamps: true})
Person.pre("find", function(next) {
this.populate("friends")
next()
})
Adding the function as a middleware to find will make it run for every person found. That includes the children in the friends array.
I've the following complex JSON object that has got array and array inside an array. How can parse those arrays and create an object array for each element in the array. I'm using lodash library in my project, just in case if there are any functions available.
{
studentId: 123
name: XYZ
phone: 34234234
gender: M
subjects: [{
studentId: 123
subjectName: Math
scores:50
assignments:[
{
type: Internal,
submitted: yes,
status: failed
},
{
type: External,
submitted: yes,
status: passed
}]
},
{
studentId: 123
subjectName: Science
score: 20
assignments:[
{
type: Internal,
submitted: yes,
status: passed
},
{
type: External,
submitted: yes,
status: failed
}]
}]
}
Expecting:
[{
studentId:123,
name: XYZ
phone: 34234234
gender: M,
subjectName: Math
scores:50
assignments:[
{
type: Internal,
submitted: yes,
status: failed
},
{
type: External,
submitted: yes,
status: passed
}]
},
{
studentId:123,
name: XYZ
phone: 34234234
gender: M,
subjectName: science
scores:20
assignments:[
{
type: Internal,
submitted: yes,
status: failed
},
{
type: External,
submitted: yes,
status: passed
}]
}
]
You can use omit to get the details of the student without the subjects array, use these details to transform each item in the subjects array using defaults through map.
var details = _.omit(data, 'subjects');
var result = _.map(data.subjects, function(subject) {
return _.defaults({}, details, subject);
});
var data = {
studentId: '123',
name: 'XYZ',
phone: '34234234',
gender: 'M',
subjects: [{
studentId: '123',
subjectName: 'Math',
scores: 50,
assignments: [{
type: 'Internal',
submitted: 'yes',
status: 'failed'
},
{
type: 'External',
submitted: 'yes',
status: 'passed'
}
]
},
{
studentId: '123',
subjectName: 'Science',
score: 20,
assignments: [{
type: 'Internal',
submitted: 'yes',
status: 'passed'
},
{
type: 'External',
submitted: 'yes',
status: 'failed'
}
]
}
]
};
var details = _.omit(data, 'subjects');
var result = _.map(data.subjects, function(subject) {
return _.defaults({}, details, subject);
});
console.log(result);
body > div { min-height: 100%; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
I encourage you to use Normalizr package. It's very useful and takes all care about your collections even if they're nested.