push data to array in Firebase - javascript

does anyone know how to push data to array in firebase without overwriting?
I use this solution, but unfortunately it overwrites the existing data:
db.collection('Goals').doc('Aqd8aP8uLSvuAgsMs5aW').update({"nested": ['12','14']})

If the items in the array are unique, you can use array union:
db.collection('Goals').doc('Aqd8aP8uLSvuAgsMs5aW')
.update({"nested": firebase.firestore.FieldValue.arrayUnion(['12','14'])})
If the items in the array are not unique, there is no way to do this with a single statement, and you will need to:
Read the document to get the array's current values.
Add the new values to the array in your application code.
Write the entire back to the document.
Also see:
How to update an "array of objects" with Firestore?
Adding already represented value in arraylist into arraylist
add object data to existing firebase document

According to the documentation https://firebase.google.com/docs/firestore/manage-data/add-data
you should merge data:
If the document does not exist, it will be created. If the document does exist, its contents will be overwritten with the newly provided data, unless you specify that the data should be merged into the existing document, as follows:
db.collection('Goals').doc('Aqd8aP8uLSvuAgsMs5aW').set({"nested": ['12','14']}, { merge: true });

You can use the Following syntax to solve the query
const handleOnSubmit = () =>{
const dataRef = db.database().ref(user['']);
const data = ({
*//data to push after every submit*
});
dataRef.push(data)
}

Possible it not best solution, but you can get current array and add new element.
const { nested } = await db.collection('Goals').doc('id');
nested.push('new element');
await db.collection('Goals').doc('id').update( { nested } );

Related

Adding an element to JSON returned from a map loop with a final Promise.all

I'm using Retool and looking up records in a Firestore table by a Document ID.
The below code works great and returns an array of JSON objects. However it does not have the appIDs[?] used in the lookup. How can I add the appIDs ('id1','id3', or 'id2') as an additional element to the matching JSON object in the array? The order of the returned array of JSON objects is not necessarily the same order as the appIDs array.
var appIDs = ['id1','id3','id2'];
var metadatas = appIDs.map(row => {
return qTile_description_v1.trigger({
additionalScope: {
appID: row
}
});
});
return Promise.all(metadatas.map(p => p.catch(error => null)));
Answer in comments.
Apparently the answer is easy since my statement that the order returned may not be the same as the order of the keys in the array is false. The order will be the same, so problem solved.

Remove surrounding array from array of object

does anyone know how I can remove a surrounding array from an array of objects? In my case, I only have one object in this array. [{"id":"6","email":"test#test.com"}] Also, would the solution work in the case of multiple objects in the array? Thanks!
You have an array of objects. That's great, because it's the easiest way to store and manipulate lists of records.
You can use array methods like .map that allow you to treat each record separately, telling it what to do individually with each element. That's also great, because it basically "removes the element from the array" while still processing the whole array, which is what I think you're after.
Simple example to create a dropdown:
const data = [{"id":"6","email":"test#test.com"}, {"id":"12","email":"test2#test.com"}];
const drawEmailDropdown = () => {
let options = data.map(d => `<option value='${d.id}'>${d.email}</option>`);
return `<select>` + options.join("") + `</select>`;
};
document.querySelector("#container").innerHTML = drawEmailDropdown();
<div id="container"></div>

Arr.push inside For-loop

I have a SPA built with Vue and I'm trying to fetch an array of items from a custom API.
Once I've stored the items I'm trying to loop through that array and push in a custom path value, however I get the error
this.list[i].push is not a function
I'm not sure why this wouldn't be possible, but I'm sure I've missed something.
this.list: []
fetch(){
let url = 'http://core.com/api/v0/sources/'
axios.get(url).then((response) => {
this.list = response.data.data
for(var i = 0; i < this.list.length; i++){
let arr = { path: '/testPath' }
this.list[i].push(arr)
}
})
}
In the comments you mentioned your goal:
"this.list[i].path does not exist, that is what Im trying to create"
...if you literally want to add a property called "path" directly under the object at this.list[i] then you'd write
this.list[i].path = '/testPath'
This will create a new property for the object being held at this.list[i].
P.S.
You don't need your (badly-named) arr variable at all here.
Using .push() doesn't make any sense (and doesn't work) because this.list[i] contains an object rather than an array, and also doing that wouldn't create a property as you wanted.
push is the function of an array but you are trying to push an object in an object that's why you got this exception.
you can do as below.
this.list[i].path = '/testPath'
path property will be dynamically added in your object this.list[i].

Iterate over array of object using map till the second last object

I am having an array of objects where all objects have the same keys except the last object. Think like array have values and to denote all these values as a whole I have a key I am pushing the key at last along with the values in the array.
homeTask is a list of object which is the values and homeTaskKey is the key to represent the homeTask
res.data.resultSet.homeTask.forEach(element => {
var singleEvent={
task:'',
taskDuration:'',
status:'',
};
singleEvent.task=element.task;
singleEvent.taskDuration=element.taskDuration;
singleEvent.status=element.status;
newEvents.push(singleEvent);
});
newEvents.push(res.data.resultSet.homeTaskKey);
addEvent(newEvents);
}
addEvent is props method of parent component where I am setting the array to state variable name as events which is array type.
When I iterate over events using map I want to skip the last object since it does not have keys like task, taskDuration and status. Therefore it won't give any problem when I fetch those values.
events.slice(0, events.length-1).map(<function>);
this will ignore the last element and all n-1 entries will be fed to map
UPDATE:
the array name is events not event therefore it should be events.length
You could still use map, but simply pop the last element off once the map completes. For example:
const newEvents = homeTask.map(({ task, taskDuration, status }) => ({
task, taskDuration, status
}))
newEvents.pop()
addEvent(newEvents)
Or just replace the last item with your taskkey, as you know the last item will be junk:
newEvents[newEvents.length - 1] = res.data.resultSet.homeTaskKey
Or just slice the array prior to mapping, and then push the taskKey at the end like you were doing. slice is safe to perform on your prop, as it shallow copies.
Or most importantly, ask yourself why you have this entirely weird data structure that has the key appended on the end. Perhaps rethink your data and not create this problem for yourself in the first place.
res.data.resultSet.homeTask.forEach((element,index) => {})
second param to function is index you, can use this to identify the second last element by comparing it with total length of array.
hmm you can try with this
res.data.resultSet.homeTask.forEach(element => {
if(!element.task)
return false;
...bla bla bla
}
The map() method creates a new array with the results of calling a function for every array element.
So it creates an array of same length from source array.
What you need is filter()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
Something like this;
const tasks = res.data.resultSet.homeTask.filter((element) => {
const { task, taskDuration, status } = element;
return task && taskDuration && status;
});

.add() in firebase cloud firestore nested objects

The firebase documentation says this about updating in nested objects: https://firebase.google.com/docs/firestore/manage-data/add-data#update_fields_in_nested_objects
My structure
let ref = db.collections('projects').doc('blabla')
ref.set({
objOfObjects: {}
})
I would like to add an object(value) with a randomly generated key to objOfObjects, much like the regular add function. I can't tie the key to any of the values of the object. Is there a way to add to objOfObjects or do I have to restructure my data?
There is no built-in function add a field with a randomly generated name to a document. But you can generate the random name yourself and add it. You can even use collection.add() to generate the random name, since (as Doug says here) that doesn't actually create a document yet.
var newId = store.collection('projects').doc().id;
let ref = db.collections('projects').doc('blabla');
var updates = {};
updates[id] = { ... }
ref.update(updates)
The tricks used here:
Get a new unique id, as explained before.
Use [] notation to use the value of that id as the property name.
Call update() to update a document, instead of replacing it.

Categories