Using observable query parameters just doesn't work. There is no way to dynamically change the limitToFirst request in the base SDK, and no way to do this in AngularFire2.
Each time the observed query parameter generates a new value, a new Firebase ref is created. You can see it in the source here .
However, it would be possible to create an observable representing an infinite list by doing something like this:
import { Observable } from "rxjs/Observable"; import { Subject } from "rxjs/Subject"; import rxjs/add/observable/defer"; import rxjs/add/observable/zip"; import rxjs/add/operator/concatMap"; import rxjs/add/operator/filter"; import rxjs/add/operator/first"; import rxjs/add/operator/map"; import rxjs/add/operator/scan"; import rxjs/add/operator/share"; import rxjs/add/operator/startWith"; const pageSize = 100; let notifier = new Subject<any>(); let last: Observable<any>; let infiniteList = Observable // Use zip to combine the notifier emissions with the last // child value: .zip(notifier, Observable.defer(() => last)) // Use concatMap to emit a page of children into the // composed observable (note that first is used to complete // the inner list): .concatMap(([unused, last]) => this.af.database.list("quests", { query: { // If there is a last value, start at that value but ask // for one more: limitToFirst: last ? (pageSize + 1) : pageSize, orderByChild: "date_published", startAt: last } }) .first() ) // Use scan to accumulate the page into the infinite list: .scan((acc, list) => { // If this isn't the initial page, the page was started // at the last value, so remove it from the beginning of // the list: if (acc.length > 0) { list.shift(); } return acc.concat(list); }, []) // Use share so that the last observable (see below) doesn't // result in a second subscription: .share(); // Each time a page is emitted, map to its last child value so // that it can be fed back into the composed infinite list: last = infiniteList .filter((list) => list.length > 0) .map((list) => list[list.length - 1].date_published) .startWith(null); infiniteList.subscribe((list) => console.log(list)); // Each time the notifier emits, another page will be retrieved // and added to the infinite list: notifier.next(); notifier.next(); notifier.next();
This will work, but if the child you are ordering for has duplicate values, AngularFire2 will not be able to reliably view the results until this question is opened and resolved again.
The resulting list is static. That is, children already on the list will not be updated if the database changes. Implementing a dynamic list is more complex since duplicate and absent children can be easily implemented using the swap mechanism based on restrictions.
After writing this answer, I made available a proven implementation of advanced and reverse, unrealistic and endless real-time observable lists in the Firebase observable object library that I have open. See this GitHub repository .
cartant
source share