Angularfire: Suggestion: Add a child() method to quickly retrieve a property as observable

Created on 4 Oct 2016  路  6Comments  路  Source: angular/angularfire

Having to manually get a new FirebaseObservable from a child property is a bit cumbersome. While it's a best practice to denormalize your database, there will be some cases with nested data:

object: FirebaseObjectObservable<any>;
list: FirebaseListObservable<any>;

let object = this.af.database.object('/object');
let list = this.af.database.list('object/childlist');

What if we could reference this property and return it as it's own observable:

object: FirebaseObjectObservable<any>;
list: FirebaseListObservable<any>;

let object = this.af.database.object('/object');
let list = object.child('childlist');

We could have a distinction between returning the observable as FirebaseListObservable / FirebaseObjectObservable

object: FirebaseObjectObservable<any>;

let listObservable = object.childList('childlist');
let objectObservable = object.childObject('childlist');

With this we could pass a new Observables much easier. Suppose we get a FirebaseListObservablereference and want to get one of the childs and return it as a FirebaseObjectObservable. We'll do this by getting the $key value from the list item and using that to get the full URI for the resource:

let listObjectObservable = this.af.database.object('/list/' + listObject.$key);

Instead we could just get the list and use the new childObject() method:

list: FirebaseListObservable<any>;
object: FirebaseObjectObservable<any>;

let object = list.childObject(listObject.$key);

So basically the child() method would make it a bit quicker to get the property as a observable. I guess using the current object's firebaseref and amending to that would be a simple solution.

But are there any pitfalls performance wise or is there a fundamental problem with my thinking?
Perhaps there are better ways to do this.

In any case thanks for the great library: it makes it very easy to handle Firebase related tasks!

feature

Most helpful comment

This would a) encourage nesting data and b) encourage synchronizing the same data twice (the child list is already present and synchronized in the parent object). We removed child() from AngularFire back in alpha, years ago, to discourage this and it saved developers a great deal of pain. I'm not in favor of adding it back in now.

All 6 comments

This would a) encourage nesting data and b) encourage synchronizing the same data twice (the child list is already present and synchronized in the parent object). We removed child() from AngularFire back in alpha, years ago, to discourage this and it saved developers a great deal of pain. I'm not in favor of adding it back in now.

I get that nesting large objects isn't the best method but we do exactly what @antti-pyykkonen mentioned:

library: FirebaseObjectObservable<any>;
itemsAf: FirebaseListObservable<any>;

constructor(private af:AngularFire) {
  this.library = this.af.database.object('path/to/lib/id');
  this.itemsAf = this.af.database.list('path/to/lib/id/items')

<h4>Library Name: {{(library |async)?.name}}</h4>
<div *ngFor="let item of itemsAf | async">
  {{item.name}}
</div>

When Angular could loop object properties it was no big deal but now it has to be an array and unpacking it requires a subscription. It was cheaper/faster to just sub twice.

Our data looks like:

libraries: {
    $key: {
        name: 'myLib',
        items: {
            $key:{name:'itemName'}
        }
    }
}

I know large scale nesting isn't the best plan but:

libraries: {
    $key: {
       name: 'myLib'
    }
}
items: {
    $libraryKey: {
        $itemKey: {name:'itemName', library:'libraryKey'}
    }
}

Would still require two bindings as well and seems like a lot of work, especially once we start adding in security rules and whatnot..

Id love to be able to do:

var library = this.af.database.list('library');
var items = library.getChild('items',true); //listObservable

function getItem(key:string) {
  return items.getChild(key); //objectObservable
}

I guess we'll have to find other ways to do this. So are there any good practices on this?

For example: would recommend to map additional Observable properties to a FirebaseListObservable like seen here.

Thanks for the responses!

So it is suggested to have rather 3 independent collections eg

Slideshow 
Slides

than nesting :
Slideshows / Slideshow / Slides
?

I used angular fire 2 with ionic 2
How to Push child with collection
I need Following Output Using angular fire 2

{
ASSIGN_TO: "2"
COMMENTS:{
dfdsfdf:{
COMP_STATUS: "OnProcess",
DATE: "2016-12-16 09:57:03"
},
fgfd:{
COMP_STATUS: "OnProcess",
DATE: "2016-12-16 09:57:03"
}
}
}
Kindly Advice me,
Thanks & Regards

I used $ref.child() method available within this.af.database.object().

Was this page helpful?
0 / 5 - 0 ratings