Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(database): support optional endAt/equalTo key #838

Merged
merged 1 commit into from
Feb 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/4-querying-lists.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ const queryObservable = af.database.list('/items', {
| `orderByKey` | Boolean to order by Firebase Database keys. |
| `orderByPriority` | Boolean to order by Firebase Database priority. |
| `orderByValue` | Specify a value to order by. |
| `equalTo` | Limit list to items that contain certain value. |
| `equalTo` <sup>1</sup> | Limit list to items that contain certain value. |
| `limitToFirst` | Sets the maximum number of items to return from the beginning of the ordered list of results. |
| `limitToLast` | Sets the maximum number of items to return from the end of the ordered list of results. |
| `startAt` <sup>1</sup> | Return items greater than or equal to the specified key or value, depending on the order-by method chosen. |
| `endAt` | Return items less than or equal to the specified key or value, depending on the order-by method chosen. |
| `endAt` <sup>1</sup> | Return items less than or equal to the specified key or value, depending on the order-by method chosen. |

<sup>1</sup> The Firebase SDK supports [an optional `key` parameter](https://firebase.google.com/docs/reference/js/firebase.database.Reference#startAt) when ordering by child, value, or priority. You can specify the `key` parameter using `startAt: { value: 'some-value', key: 'some-key' }`
<sup>1</sup> The Firebase SDK supports an optional `key` parameter for [`startAt`](https://firebase.google.com/docs/reference/js/firebase.database.Reference#startAt), [`endAt`](https://firebase.google.com/docs/reference/js/firebase.database.Reference#endAt), and [`equalTo`](https://firebase.google.com/docs/reference/js/firebase.database.Reference#equalTo) when ordering by child, value, or priority. You can specify the `key` parameter using an object literal that contains the `value` and the `key`. For example: `startAt: { value: 'some-value', key: 'some-key' }`.

## Invalid query combinations

Expand Down
80 changes: 80 additions & 0 deletions src/database/firebase_list_factory.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,86 @@ describe('FirebaseListFactory', () => {

});

describe('equalTo(value, key)', () => {

it('should support the optional key parameter to equalTo', (done) => {

questions.$ref.ref.set({
val1: Object.assign({}, val1, { data: 0 }),
val2: Object.assign({}, val2, { data: 0 }),
val3: Object.assign({}, val3, { data: 0 })
})
.then(() => {

let query1 = FirebaseListFactory(`${rootDatabaseUrl}/questions`, {
query: {
orderByChild: 'data',
equalTo: { value: 0 }
}
});
query1 = take.call(query1, 1);
query1 = toPromise.call(query1);

let query2 = FirebaseListFactory(`${rootDatabaseUrl}/questions`, {
query: {
orderByChild: 'data',
equalTo: { value: 0, key: 'val2' }
}
});
query2 = take.call(query2, 1);
query2 = toPromise.call(query2);

Promise.all([query1, query2]).then(([list1, list2]) => {
expect(list1.map(i => i.$key)).toEqual(['val1', 'val2', 'val3']);
expect(list2.map(i => i.$key)).toEqual(['val2']);
done();
});
})
.catch(done.fail);
});

});

describe('endAt(value, key)', () => {

it('should support the optional key parameter to endAt', (done) => {

questions.$ref.ref.set({
val1: Object.assign({}, val1, { data: 0 }),
val2: Object.assign({}, val2, { data: 0 }),
val3: Object.assign({}, val3, { data: 0 })
})
.then(() => {

let query1 = FirebaseListFactory(`${rootDatabaseUrl}/questions`, {
query: {
orderByChild: 'data',
endAt: { value: 0 }
}
});
query1 = take.call(query1, 1);
query1 = toPromise.call(query1);

let query2 = FirebaseListFactory(`${rootDatabaseUrl}/questions`, {
query: {
orderByChild: 'data',
endAt: { value: 0, key: 'val2' }
}
});
query2 = take.call(query2, 1);
query2 = toPromise.call(query2);

Promise.all([query1, query2]).then(([list1, list2]) => {
expect(list1.map(i => i.$key)).toEqual(['val1', 'val2', 'val3']);
expect(list2.map(i => i.$key)).toEqual(['val1', 'val2']);
done();
});
})
.catch(done.fail);
});

});

describe('observable queries (issue #830)', () => {

it('should not emit the results of previous queries', (done) => {
Expand Down
10 changes: 9 additions & 1 deletion src/database/firebase_list_factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ export function FirebaseListFactory (

// check equalTo
if (utils.hasKey(query, "equalTo")) {
queried = queried.equalTo(query.equalTo);
if (utils.hasKey(query.equalTo, "value")) {
queried = queried.equalTo(query.equalTo.value, query.equalTo.key);
} else {
queried = queried.equalTo(query.equalTo);
}

if (utils.hasKey(query, "startAt") || utils.hasKey(query, "endAt")) {
throw new Error('Query Error: Cannot use startAt or endAt with equalTo.');
Expand Down Expand Up @@ -78,7 +82,11 @@ export function FirebaseListFactory (
}

if (utils.hasKey(query, "endAt")) {
if (utils.hasKey(query.endAt, "value")) {
queried = queried.endAt(query.endAt.value, query.endAt.key);
} else {
queried = queried.endAt(query.endAt);
}
}

if (!utils.isNil(query.limitToFirst) && query.limitToLast) {
Expand Down