paweloque
paweloque

Reputation: 18864

How to properly query a Firebase list in AngularFire2?

I'm developing an Angular2 application with Firebase as a backend. On a subpage I want to display some tasks for a given week which is specified by a route parameter.

I'm using a BehaviorSubject as a parameter to the AngularFire2 query the following way:

export class PrepareComponent implements OnInit {

    private routeSub: any;
    weekId = '';

    private weekSubject: BehaviorSubject<any> = new BehaviorSubject('weekId');

    taskTemplates$: FirebaseListObservable<TaskTemplate[]>;

    constructor(private route: ActivatedRoute,
                private router: Router,
                private angularFire: AngularFire) {

        // this.taskTemplates$ = angularFire.database.list("/taskTemplates");

Here is the Firebase query:

        this.taskTemplates$ = angularFire.database.list("/taskTemplates", {
            query: {
                equalTo: this.weekSubject
            }
        });
    }

    ngOnInit() {
        this.routeSub = this.route.params.map(
            (params: Params) => this.weekId = params[ 'weekid' ]
        ).subscribe(
            weekId => this.weekSubject.next(weekId)
        );
    }

    ngOnDestroy() {
        this.routeSub.unsubscribe();
    }
}

Unfortunately, the Firebase taskTemplates$ observable is not returning any data for the given weekId.

I assumed that once the weekId will be set by querying the route parameters, the list would get it as a query parameter and return the data which has: { weekId: actualWeekId, ...}.

EDIT Added an example of data stored in Firebase:

  {
   "-Kc_E0U4UOl9PPtxpzCM" : {
   "description" : "asdfasdf",
   "weekId" : "99f2"
  },
  "-Kc_E3wv3fhpUt56sM4u" : {
    "description" : "another task",
    "weekId" : "99f2"
  }
}

So what I want to do is to get all records for a given weekId

Upvotes: 3

Views: 16119

Answers (2)

Rob
Rob

Reputation: 2323

If anyone is having a hard time like me nowadays, this might help you guys:

db.list('/items', ref => ref.orderByChild('size').equalTo('large'))

Please refer to https://github.com/angular/angularfire2/blob/master/docs/rtdb/querying-lists.md

for more information!

Upvotes: 23

cartant
cartant

Reputation: 58400

The core problem appears to be the query that's specified when the list observable is created.

Given the structure of the data, it seems that orderByChild is what should be used, as you appear to be wanting to select the entries that have a particular weekId.

The query in the question's code will be looking for entries that have keys equal to the weekid obtained from the activated route. However, the keys are push keys, like -Kc_E0U4UOl9PPtxpzCM.

You can also simplify the code somewhat by composing the query observable directly from the activated route. Something like this should do what you want:

export class PrepareComponent implements OnInit {

  taskTemplates$: FirebaseListObservable<TaskTemplate[]>;

  constructor(
    private route: ActivatedRoute,
    private router: Router,
    private angularFire: AngularFire
  ) {}

  ngOnInit() {
    this.taskTemplates$ = this.angularFire.database.list("/taskTemplates", {
      query: {
        orderByChild: 'weekId',
        equalTo: this.route.params.map((params: Params) => params['weekid'])
      }
    });
  }
}

If you are using orderByChild you will likely see a console warning about an index - if you've not already created one. You need to use the security rules to do that. It should be explained well enough in the documentation.

Upvotes: 4

Related Questions