Honey Darling

I feel good about this

Firebase Priority and AngularFire

I recently worked through building a sample application using AngularJS and AngularFire (the officially supported AngularJS API for working with Firebase). You can see the results of my experiments here: https://github.com/honeyd/my-points.

Firebase doesn’t have a ton of ways to query data. Essentially, you have three choices:

  1. Design the data structure so that locations represent queried data
  2. After retrieval, filter the results yourself
  3. Use priority

For my example app, I needed a way to pull all items that occurred between two dates. When I retrieve the children of a Firebase location, I can specify some boundaries.

1
2
3
4
5
var ref = new Firebase('https://firebase-url/items');
// explicit data binding (1-way)
$scope.items = angularFireCollection(ref.startAt(1).endAt(10));
// implicit data binding (2-way)
// angularFire(ref.startAt(1).endAt(10), $scope, 'items');

In this example, $scope.items will include all items with a priority between 1 and 10 inclusive.

Unfortunately, using implicit data binding (angularFire()) on a location that represents an array is problematic at the time of this writing. When the location is loaded into your model, priority is not taken into account, and will be removed the first time the data is saved back to Firebase. See issue 116.

So angularFire() is out and angularFireCollection() is in.

The difference between angularFire() and angularFireCollection() is that angularFire() will set up implicit, or 2-way data binding with your AngularJS model, and angularFireCollection() will only be 1-way, but provide a lot more flexibility.

angularfire()

When I associate a location with my model,

1
angularFire(new Firebase('https://firebase-url/items'), $scope, 'items')

any changes I make to that model ($scope.items) will change the Firebase data as well. This is real nice. I can use $scope.items.push({name: 'Sweetness'}) and $scope.items.splice(0, 1) and $scope.items[0].name = 'Awesome' to my heart’s content.

angularFireCollection()

I can assign a Firebase location to any variable I like, but this variable will not be watched for changes and will not modify the Firebase location unless I call the appropriate methods. The good news is that I can use angularFireCollection() to preserve the priority I have already set on an item as well as set a priority when an item is created or updated.

1
2
$scope.items = angularFireCollection(new Firebase('https://firebase-url/items'));
$scope.items.add({name: 'Yes'}).setPriority(1);

The other good news about using angularFireCollection() is that the ordering of items is better than when using angularFire(), but it’s not perfect. See issue 19.

To see these ideas in action, visit my sample app, or http://plnkr.co/edit/3AfFfo, or https://github.com/honeyd/my-points.

I have my eye on the AngularFire repo for updates to the issues referenced in this post. I’ll edit as AngularFire evolves.

Comments