question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

@FirebaseList and @FirebaseObject design

See original GitHub issue

Goal: Have a declarative means of getting a Firebase reference into a component, to be used in a view.

Proposal:

@Component({
  selector: 'posts-list',
  changeDetection: ChangeDetectionStrategy. OnPush
  template: `
  <ul>
    <li *ngFor="#post in posts | async">
      {{post.val().title}} 
      <button (click)="posts.remove(post)">X</button>
    </li>
  </ul>
  `
})
class PostsList {
  @FirebaseList({
    path: 'https://<FIREBASE>/posts' // Should eventually support relative to an injectable root.
  }) posts:Observable<Post>;

The @FirebaseList decorator would create a subclassed Observable and set it to posts. The Observable would contain methods for updating the data. It’s generally considered bad practice to add non-combinator methods to an Observable, but there was no cleaner alternative that came to mind (I’m hoping for ideas!). Since the type is an Observable it can be unwrapped with the async pipe inside the template, and can take advantage of OnPush change detection to only perform dirty checking when a new array has been emitted from the Observable.

The FirebaseListObservable would support save, add, and remove similar to AngularFire, as well as lookup helpers to find items by key or find index of an item.

This design has the values inside the list as wrapped Firebase objects instead of POJS, which means .val() must be called inside the template. This is to make it easier to update data without having to reverse lookup records. There could be a pipe that would unwrap all objects, or developers could just map themselves:

<li *ngFor="#post in posts | af_unwrap | async">
class PostsList {
  postsUnwrapped:Observable<Post>;
  @FirebaseList(...) posts:Observable<Firebase>;
  constructor() {
    this.postsUnwrapped = this.posts.map(v => v.val());
  }
}

This decorator is called @FirebaseList. There will be a separate decorator with similar semantics but for objects, called @FirebaseObject.

Querying

Query operators may optionally be supplied to the decorator:

@FirebaseList({
  path: 'https://<FIREBASE>/posts',
  query: [['orderByChild', 'timestamp'], ['limitToFirst', 2]]
})

Prior Art https://www.firebase.com/docs/web/libraries/angular/api.html#angularfire-firebasearray

The utilities used to make this functionality would carry over to the yet-to-be-designed Firebase pipe. The pipe would probably be the preferred tool for developers not familiar with, or able to use decorators.

I’ve got a branch with a functioning FirebaseList decorator that I’ll push soon.

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:22 (11 by maintainers)

github_iconTop GitHub Comments

1reaction
jeffbcrosscommented, Jan 21, 2016

Another thing I forgot to include in the proposal was how to manage pagination, or making the query more interactive. I want to make it possible to incorporate scalar or observable values into the query part of the list. And when new values would be pushed to an observable, the query would be re-performed underneath.

Since the decorator definition object doesn’t have access to the class instance, it wouldn’t be possible to include direct references to class properties in the annotation. So there needs to be a way to reference the property by name instead of reference. The two ideas that come to mind are a string-based DSL to specify interpolated properties, i.e. query: [['limitToFirst', '{{pageSize}}']] and a more explicit approach using functions to designate dynamic values: query: [['limitToFirst', observableQuery('pageSize')]]. I lean toward the 2nd, explicit option.

0reactions
jeffbcrosscommented, Feb 2, 2016

Closing in favor of #39

Read more comments on GitHub >

github_iconTop Results From Across the Web

Structure Your Database - Firebase - Google
This guide covers some of the key concepts in data architecture and best practices for structuring the JSON data in your Firebase Realtime...
Read more >
Firebase Lists vs Objects - Stack Overflow
When I use firebase.object('user') the keys are available. This is what it looks like when I request 'user' as a list:.
Read more >
Angular, Firebase and AngularFire Crash Course
This is an introduction to Firebase, Data Modeling, and the AngularFire library, how to build backends using Firebase, including custom ...
Read more >
AngularFire2のAPI速習 - Qiita
... AngularFire) { // 下記「FirebaseList」を見てください let itemList = af.database.list('/items'); // 下記「FirebaseObject」を見てください ...
Read more >
how to convert firebase object? to map<String , dynamic ...
How to filter a Firebase list of object contains timestamp in flutter based on start and end ... how to do design like...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found