Reputation: 5958
I have a question about adding arrays to Firebase using AngularFire. Let's start with a quick example. What I tend to do when my users on the front end create a list is something like this:
angular.module("app", ["firebase"])
.controller("createListCtrl", function($scope, $firebaseArray) {
console.log("controller loaded");
$scope.newList = [];
$scope.addItemToList = function(itemlist) {
console.log(itemlist);
$scope.newList.push({
"item": itemlist,
"done": false
});
}
$scope.sendToDb = function() {
var ref = new Firebase("https://xxxxxx.firebaseio.com");
var list = $firebaseArray(ref);
list.$add({
"list": $scope.newList
}).then(function(ref) {
var id = ref.key();
console.log("added record with id " + id);
console.log(list.$indexFor(id)); // returns location in the array
})
}
Ok all nice and dandy and it all works great but I then I read this article: https://www.firebase.com/blog/2014-04-28-best-practices-arrays-in-firebase.html
And I heard more people say to avoid arrays and I see the problem with array in Firebase, but what is the alternative, the article says this structure:
{foo: {counter: 1}, bar: {counter: 1}, baz: {counter: 1}};
Is that really a better structure? I think it gets messy and I don't even know how I would achieve this structure starting with something like this:$scope.newList = {};
. Is it really a problem doing it with an array. Are arrays really evil in Firebase? Thanks in advance for an explanation or a better alternative.
edit
This is how the list is stored in Firebase, which does not seem very good:
---uniqueID
---list
---0
---done:false
---item:"item1"
---1
---done:false
---item:"item2"
---2
---done:false
---item:"item3"
Upvotes: 1
Views: 743
Reputation: 600130
The $firebaseArray
class, which you're already using, provides a mapping between Firebase's ordered collections (which use push ids for their keys) and AngularJS's array (which use regular arrays).
So in your controller's constructor instead of creating a local array for itemList
, create a two-way synchronized $firebaseArray
:
$scope.newList = $firebaseArray(new Firebase("https://xxxxxx.firebaseio.com"));
The blog post you're referring to served as the basis for quite a few changes to AngularFire since then. I highly recommend that you work through the AngularFire development guide. It will take at most a few hours and will answer many more questions than just this one (which is covered in the section on synchronized arrays).
Thanks for the update. I now get what you're trying to do. So you initially want to keep the list of items client-side only, and then all at once save it to Firebase.
In that case, I'd write sendToDb
like this:
$scope.sendToDb = function () {
var ref = new Firebase("https://xxxxxx.firebaseio.com");
var listRef = ref.push();
$scope.newList.forEach(function(item) {
var itemRef = listRef.push({ item: item.item, done: item.done });
console.log('Added item with key: '+itemRef.key());
});
}
This uses the regular Firebase JavaScript SDK. But since AngularFire is built on top of that, they will co-exist without problems.
So instead of pushing the array in one go, I simply loop over the items in it and push each of them.
Working fiddle here: https://jsfiddle.net/frankvanpuffelen/vnh5dbwq/11/
Upvotes: 1