Angularfire: Passing an optional parameter to startAt() when querying FirebaseListObservable

Created on 17 Jul 2016  路  11Comments  路  Source: angular/angularfire

Hey,

I'm using a FirebaseListObservable to retrieve some messages from firebase and I was wondering how to use the firebase query startAt() method inside the query object. It's not a simple startAt(value) call, since I need to pass in the optional "key" parameter. However, it seems that there's no easy or straightforward way to accomplish that within the query object.

I tried the following:

    this.af.database.list('/messages', { 
    query: { 
        orderByChild: 'date', 
        startAt: {value: 'Some date', key: 'some key'}, //key is the optional parameter 
        limitToFirst: 10
        }
        })

but the firebase library (not angularfire2) complains:

ORIGINAL EXCEPTION: Error: Query: First argument passed to startAt(), endAt(), or equalTo() cannot be an object.

The startAt method can receive an optional parameter "key", as described in the firebase docs:
https://firebase.google.com/docs/reference/js/firebase.database.Query#startAt

I even tried $value and $key as the object properties, but firebase threw another Error.

Is this impossible to do with angularfire or is there a different syntax to do it?

This is how the query looks like with vanilla firebase:
firebase.database().ref('/messages').orderByChild('date').startAt(startAtValue, someKey).limitToFirst(10);

bug

Most helpful comment

@davideast What would the option be fore querying date ranges if this will not be supported?

All 11 comments

Thanks for bringing this up @lf-alves. This is a case we missed in the original implementation. We'll work on it fixing it for the upcoming release.

Hey @lf-alves, upon further review I'm inclined to not support this feature as it works for priority use cases. While it is something supported by the SDK, I'm not keen on fully supporting priority as it is not the recommended way of doing things for awhile now. Most things priority does is easily achieved using the other querying methods.

I'm closing this issue, but feel free to respond with comments.

@davideast What would the option be fore querying date ranges if this will not be supported?

@davideast When looking at this SO question, I was curious as to how the optional key parameters to startAt, endAt and equalTo worked. The documentation for startAt suggests that using the optional key parameter is not limited to priority:

The child key to start at. This argument is allowed if ordering by child, value, or priority.

However, the docs for the endAt and equalTo state that "argument is only allowed if ordering by priority."

I've done some experimenting and it seems that the key parameter can be specified when ordering by child when using startAt, endAt or equalTo.

Are the docs now wrong? Given that it doesn't appear to be limited to priority, shouldn't this be implemented in AngularFire2? It would be straightforward to add optional startAtKey, endAtKey and equalToKey options to the list's query.

The optional second parameter is a legacy feature. AngularFire2 won't be supporting priorities and you can achieve better behavior through orderByChild() and we will encourage this practice going forward.

@katowulf @davideast I don't think I've made my point clearly. I'll create a proper issue for this. According to the SDK documentation, an optional key parameter is supported for startAt when using orderByChild and without it paging is not always possible with non-unique child values.

Once again, the optional second parameter (i.e. a key) is used with orderByPriority(), which is a legacy feature that existed before orderByChild(), orderByKey(), and orderByValue() existed.

You should prefer orderByChild() and in in this case you only pass one parameter into startAt, endAt, et al.

@katowulf According to the SDK docs for startAt, the optional "argument is allowed if ordering by child, value, or priority." It's the docs for equalTo and endAt that mention that its use is limited to priority.

If it were not able to be used with orderByChild, it would impossible to page through results in which the number of non-unique child values exceeds the page size.

So either the SDK docs are wrong or it's impossible to reliably page when ordering by non-unique child values.

Yep, looks like this has been updated since David and I read the spec last. Thanks for your patience in explaining. Wonder if it actually works? : ) [hint: I assume so]

@davideast may be worth revisiting this decision.

@katowulf Yep. It works. It works with orderByChild and equalTo and endAt, too, but as the docs state that usage with those is supposed to be for priority only, I'm supposing that can change. It's useful enough if only supported for startAt.

If you want, I'll create a new issue with a Plunker so that you can see for yourself.

As for supporting it in AngularFire2, doing what the OP suggested - startAt: { value: 'some-value', key: 'some-key' } - would be a straightforward, non-breaking change, as startAt is declared as any.

@katowulf @davideast There's a Plunker here that pages using the SDK's optional key parameter to startAt when ordering by child.

Was this page helpful?
0 / 5 - 0 ratings