Get array of ids from object array in firestore - arrays

in firestore I have a document with two strings and also an object array with [{email: ..., id: ..., nickname: ...} {...}]
I use a subscription to get all users from that specific document. The next step is to extract all ids from that object array (called "users") in a new array.. But I have no idea how to do this.
I try somethink like this:
this.group.forEach(element => console.log(element)
"this.group" is the subscription of that document. But this output display all content from this document and not the only array called (users)See attachement.
Hope anyone can help?

You can loop it and push it in a new array like this. See sample code below:
const docSnap = await getDoc(docRef);
const newArray = [];
if (docSnap.exists()) {
const users = docSnap.data().users
users.forEach(element => {
newArray.push(element.id);
})
// This will return an array of `id` from the `users` array.
console.log(newArray);
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
The same logic will be applied if you use it to the subscription of the document.

Related

Sequalize save array of items

I have many to many relations between the two tables actors and movies I try to execute this code but sequalize don't save actors
const arr = [];
actors.forEach((element:string) => {
const x = this.actorsService.createActor(element);
arr.push(x);
});
await Promise.all(arr);
const movie = await this.moviesRepository.create({
...dto,
actors: arr,
});
Firstly, I get an array of strings (actors); for each element, I create a new actor inside createActor. Later I want to put that data into a movie but anything I don't save
The arr still stores promises and not the actor instances. You need to store the result of Promise.all to get actor instances:
const arr = await Promise.all(actors.map(x => this.actorsService.createActor(x)));
const movie = await this.moviesRepository.create({
...dto,
actors: arr,
});

Subscribe to an observable and put values into an array

I'm new in angular and I need some help.
I have an observable getting users of type User[]
User: [
id: string,
name: string
]
and I have another array Ids of type string getting the ids of the selected users from a mat-select
Ids = this.Form.controls['users'].value
what I need right now is to subscribe to users$ observable, and get only the users that they have an id in Ids
const selectedUsers = ids.forEach(id =>this.usersSub$.value.filter((user) => user.userId === id))
something like the above but it is not really the right thing to do because it returns undefined . I'm wondering how should I properly get my selectedUsers array.
You use combineLatest to merge both observables and map all elements to accomplish it.
First, Create an observable with ids.
selectedIds$ = of([1, 3]);
players$ = of([
{ id: 1, name: 'lebron' },
{ id: 2, name: 'irving' },
{ id: 3, name: 'love' },
]);
Next, combine both observables, using the combineLatest operator, and return the players using the map to iterate over the response from the combineLast, use the filter and find to match the playerid with the ids from the selectedIds array.
const seletedUsers$ = combineLatest([this.selectedIds$,
this.players$])
.pipe(
map(([ids, players]) => {
return players.filter((p) => ids.find((id) => id === p.id));
})
)
.subscribe((v) => {
console.log(v);
});
https://rxjs.dev/api/index/function/combineLatest
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

How to convert JSON object into an array in React Native

I am getting a JSON object from Firebase. I am trying to convert it into an array of objects.
I can solve this by getting childs from Firebase one-by-one and add them into array however, that is not a good practice for my case.
The format of JSON object is as following:
key: {
id1: {some stuff here},
id2: {some other stuff},
...
}
Now what I want to get from this JSON object is :
arrayName: [
{id1:{some stuff here},
id2:{some other stuff}
]
Hope my description if fully understandable.
Any help would be appreciated
This is just plain javascript, it has nothing to do with react native. By the way, you can use Object.keys to get an array with all the keys, then map the strings as objects:
const x = {foo: 11, bar: 42};
const result = Object.keys(x).map(key => ({[key]: x[key]}));
console.log(result);
This code worked for me.
const JSONString = res.data;
object = JSON.parse(JSONString);
array = Object.keys(object).map(function(k) {
return object[k];
});
Where res.data is the response I am getting from an api
Using Object.entries, you can avoid the extra hash lookup on every item.
const x = { foo: 11, bar: 42 };
const result = Object.entries(x).map(([key, val]) => ({
[key]: val
}));
console.log(result);

Manipulate deep nested arrays in MongoDB

I have a rather convoluted array structure with 4 nested arrays that I need to manipulate with Mongoose/MongoDB. My code works but it doesn't get the beauty prize.
Right now i have a helper function that will look for an object of said ID and if it doesnt, it will $addToSet and return the array for further manipulation. This feels really clunky and i'm sure some query wizardry will fix this in a simple findOneAndUpdate().
The object structure is as follows:
bookshelf as an Array
Branch Object with an id and an array called Categories
Categories Object with an id and an array called Learnings
Learnings Object with an id and an array called Modules
Modules Object with an id and an array called Cards
It's setup this way due to the collection being one directional in terms of relationships and the documents have no parents. So for the sake of a bookmark functionality, i'm storing the whole path. So a Module could have several cards inside of it.
// TODO can probably do this in some advanced query
addtobookshelf: async function (req, res, next) {
if(!req.body.branch)
return next(boom.badRequest('No Branch id supplied.'));
if(!req.body.category)
return next(boom.badRequest('No Category id supplied.'));
if(!req.body.learning)
return next(boom.badRequest('No Learning id supplied.'));
if(!req.body.module)
return next(boom.badRequest('No Module id supplied.'));
if(!req.body.card)
return next(boom.badRequest('No Card id supplied.'));
try{
const saveslot = await SaveSlot.findOne({'owner':req.decoded._id});
let branchObject = profile.manipulateBookmark(saveslot.bookshelf, req.body.branch);
let categoryObject = profile.manipulateBookmark(branchObject.categories, req.body.category);
let learningObject = profile.manipulateBookmark(categoryObject.learnings, req.body.learning);
let moduleObject = profile.manipulateBookmark(learningObject.modules, req.body.module);
// Finally add the card
moduleObject.cards.addToSet(req.body.card);
await saveslot.save();
return res.status(200).json({message: 'succes', data: saveslot.bookshelf});
} catch(err){
console.log(err);
return next(boom.internal('Woops, something went wrong. Sorry!'));
}
},
manipulateBookmark: function(objectArray, id){
let obj;
objectArray.forEach((element) => {
if(element.id.toString() === id){
obj = element;
return;
}
});
if(!obj){
obj = objectArray.addToSet({id:id})[0];
}
return obj;
},
It's readable so that counts but I'd like to improve my query skills.
[EDIT] Added data structure for clarification
{
"bookshelf": [{
"id": "59034709d44f340011bb8307",
"categories": [{
"id": "58c27aa7734d1d46588667ab",
"learnings": [{
"id": "5881d1f62fd76911007a4ae5",
"modules": [{
"id": "5881d2962fd76911007a4ae8",
"cards": ["5881d5892fd76911007a4ae1"]
}]
}]
}]
}]
}

For...in loop is adding keys instead of values when sending to Firestore

I have an object, which contains some variables and an array. I'm trying to add the data to Firebase. Firebase didn't like the array. My solution was to convert the array to an object and send the object values to an array in Firestore using a For...in loop and a Firestore array query. This almost worked but, for some reason, my code is adding the key names instead of the values, What am I doing wrong?
let projectId = Math.floor(Math.random() * 10000);
let docTitle = this.projectTitle.title;
this.pages.forEach((page) => {
let pageT = page.pageTitle;
let pageD = page.pageDesc;
let id = page.id;
let blocks = page.blocks;
db.collection(docTitle + projectId).doc(pageT).set({
page: {pageTitle:pageT, pageDesc: pageD, id:id }
})
.then(function() {
console.log("Document successfully written!");
})
.catch(function(error) {
console.error("Error writing document: ", error);
});
// Converts array into object and adds object values to an array in firestore
let newBlocks = Object.assign({}, blocks);
for(let block in newBlocks){
db.collection(docTitle + projectId).doc(pageT).update({
blocks: firebase.firestore.FieldValue.arrayUnion(block)
})
}
})
Here are the Firestore docs on updating arrays: https://firebase.google.com/docs/firestore/manage-data/add-data#update_elements_in_an_array
Use for…of to iterate over the values in an iterable,
Change
for(let block in newBlocks){
To
for(let block of newBlocks){
for...in iterates over object keys hence for...of correct in your case

Resources