Say person
can have multiple cars
, and car
can have multiple accidents
. So we could have:
# Person with no cars
person:
name: "Misha"
cars: []
# Person with free-accident car
person:
name "Arlen"
cars:
0:
name: "Toyota"
accidents: []
Firebase stores these people as:
person:
name: "Misha"
and
person:
name "Arlen"
cars:
0:
name: "Toyota"
So in JavaScript I have to do following to restore the empty arrays: (CoffeeScript)
if person.cars?
for car in person.cars
car.accidents = [] unless car.accidents?
else
person.cars = []
Is there a better way to handle empty arrays in Firebase without writing this needless JavaScript code?
I think that, if I understand the core question, the short answer is that there is no way to force an empty array into Firebase. However, there are some paradigms that might work better than what you have above.
Keep in mind that Firebase is a real-time environment. The number of cars and accidents can (and will) change at any time. It's best to treat everything as new data arriving in real time and avoid even thinking about exists or doesn't exist.
// fetch all the people in real-time
rootRef.child('people').on('child_added', function(personSnapshot) {
// monitor their cars
personSnapshot.ref().child('cars', 'child_added', function(carSnapshot) {
// monitor accidents
carSnapshot.ref().child('accidents', 'child_added', function(accidentSnapshot) {
// here is where you invoke your code related to accidents
});
});
});
Note how there is no need for if exists/unless
type logic. Note that you would probably also want to monitor child_removed
on cars
and people
and call ref.off()
to stop listening to specific children.
If for some reason you want to stick with the static model, then forEach will become your friend:
// fetch all the people as one object, asynchronously
// this won't work well with many thousands of records
rootRef.child('people').once('value', function(everyoneSnap) {
// get each user (this is synchronous!)
everyoneSnap.forEach(function(personSnap) {
// get all cars (this is asynchronous)
personSnap.ref().child('cars').once('value', function(allCars) {
// iterate cars (this is synchronous)
allCars.forEach(function(carSnap) { /* and so on */ });
});
});
});
Note how, even with forEach, there is no need for "exists or unless" sort of logic.
I usually use the DataSnapshot function numChildren() to see if it's empty of not, like this
var fire = new Firebase("https://example.firebaseio.com/");
fire.once('value', function(data){if (data.numChildren() > 0){ /*Do something*/ });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With