Skip to content

Commit ce214a7

Browse files
author
Kamil Kisiela
committed
fix(ApolloQueryObservable): Make it compatible with Rx.Observable
1 parent 962b315 commit ce214a7

File tree

3 files changed

+121
-43
lines changed

3 files changed

+121
-43
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- Added `fetchMore` support ([PR #58](https://github.com/apollostack/angular2-apollo/pull/58))
66
- Exposed `ApolloQueryObservable` in the index module ([PR #54](https://github.com/apollostack/angular2-apollo/pull/54))
77
- Added support for getting `loading` state from ApolloQueryResult [Issue #36](https://github.com/apollostack/angular2-apollo/issues/36) ([PR #43](https://github.com/apollostack/angular2-apollo/pull/43))
8+
- Fixed `ApolloQueryObservable` incompatibility with `Rx.Observable` ([PR #59](https://github.com/apollostack/angular2-apollo/pull/59))
89

910
### v0.4.1
1011

src/apolloQueryObservable.ts

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,11 @@
1-
import {
2-
Observable,
3-
} from 'rxjs/Observable';
1+
import { Observable } from 'rxjs/Observable';
2+
import { Subscriber } from 'rxjs/Subscriber';
3+
import { Subscription } from 'rxjs/Subscription';
4+
import { Operator } from 'rxjs/Operator';
5+
import { $$observable } from 'rxjs/symbol/observable';
46

5-
import {
6-
Operator,
7-
} from 'rxjs/Operator';
8-
9-
import {
10-
Subscriber,
11-
} from 'rxjs/Subscriber';
12-
13-
import {
14-
Subscription,
15-
} from 'rxjs/Subscription';
7+
import { FetchMoreOptions } from 'apollo-client/ObservableQuery';
8+
import { FetchMoreQueryOptions } from 'apollo-client/watchQueryOptions';
169

1710
export class ApolloQueryObservable<T> extends Observable<T> {
1811
constructor(public apollo: any, subscribe?: <R>(subscriber: Subscriber<R>) => Subscription | Function | void) {
@@ -28,6 +21,8 @@ export class ApolloQueryObservable<T> extends Observable<T> {
2821
return observable;
2922
}
3023

24+
// apollo-specific methods
25+
3126
public refetch(variables?: any): Promise<any> {
3227
return this.apollo.refetch(variables);
3328
}
@@ -39,4 +34,15 @@ export class ApolloQueryObservable<T> extends Observable<T> {
3934
public startPolling(p: number): void {
4035
return this.apollo.startPolling(p);
4136
}
37+
38+
public fetchMore(options: FetchMoreQueryOptions & FetchMoreOptions): Promise<any> {
39+
return this.apollo.fetchMore(options);
40+
}
41+
42+
// where magic happens
43+
44+
protected _subscribe(subscriber: Subscriber<T>) {
45+
const apollo = this.apollo;
46+
return apollo[$$observable]().subscribe(subscriber);
47+
}
4248
}

tests/apolloQueryObservable.ts

Lines changed: 100 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,120 @@
1-
import {
2-
Observable,
3-
} from 'rxjs/Observable';
4-
51
import {
62
ApolloQueryObservable,
73
} from '../src/apolloQueryObservable';
84

5+
import {
6+
mockClient,
7+
} from './_mocks';
8+
9+
import gql from 'graphql-tag';
10+
911
import 'rxjs/add/operator/map';
1012

11-
class ObservableQuery<T> extends Observable<T> {
12-
refetch(v?: any) {}
13-
stopPolling() {}
14-
startPolling(n?: any) {}
15-
}
13+
const query = gql`
14+
query heroes {
15+
allHeroes {
16+
heroes {
17+
name
18+
}
19+
}
20+
}
21+
`;
22+
const data = {
23+
allHeroes: {
24+
heroes: [{ name: 'Mr Foo' }, { name: 'Mr Bar' }],
25+
},
26+
};
1627

1728
describe('ApolloQueryObservable', () => {
18-
it('should be able to call refetch()', () => {
19-
const obs = new ObservableQuery();
20-
const res = new ApolloQueryObservable(obs);
21-
const variables = { foo: true };
22-
23-
spyOn(obs, 'refetch').and.returnValue('refetch');
29+
let obsApollo;
30+
let obsQuery;
31+
let client;
2432

25-
expect(res.refetch(variables)).toEqual('refetch');
26-
expect(obs.refetch).toHaveBeenCalledWith(variables);
33+
beforeEach(() => {
34+
client = mockClient({
35+
request: { query },
36+
result: { data },
37+
});
38+
obsApollo = client.watchQuery({ query });
39+
obsQuery = new ApolloQueryObservable(obsApollo);
2740
});
2841

29-
it('should be able to call stopPolling()', () => {
30-
const obs = new ObservableQuery();
31-
const res = new ApolloQueryObservable(obs);
42+
describe('regular', () => {
43+
it('should be able to subscribe', () => {
44+
expect(() => {
45+
obsQuery.subscribe({
46+
next() {},
47+
});
48+
}).not.toThrow();
49+
});
50+
51+
it('should be able to receive data', (done) => {
52+
obsQuery.subscribe({
53+
next(result) {
54+
expect(result.data).toEqual(data);
55+
done();
56+
}
57+
});
58+
});
59+
60+
it('should be able to receive an error', (done) => {
61+
obsQuery.subscribe({
62+
next() {},
63+
});
3264

33-
spyOn(obs, 'stopPolling').and.returnValue('stopPolling');
65+
obsQuery.subscribe({
66+
error(error) {
67+
expect(error instanceof Error).toBe(true);
68+
done();
69+
},
70+
})
71+
});
3472

35-
expect(res.stopPolling()).toEqual('stopPolling');
36-
expect(obs.stopPolling).toHaveBeenCalled();
73+
it('should be able to use a operator', (done) => {
74+
obsQuery.map(result => result.data).subscribe({
75+
next(result) {
76+
expect(result).toEqual(data);
77+
done();
78+
},
79+
});
80+
});
3781
});
3882

39-
it('should be able to call custom method after operator', () => {
40-
const obs = new ObservableQuery();
41-
spyOn(obs, 'refetch').and.returnValue('refetch');
83+
describe('apollo-specific', () => {
84+
it('should be able to refech', () => {
85+
spyOn(obsApollo, 'refetch').and.returnValue('promise');
86+
87+
const arg = 'foo';
88+
const result = obsQuery.refetch(arg);
89+
90+
expect(obsApollo.refetch).toHaveBeenCalledWith(arg);
91+
expect(result).toBe('promise');
92+
});
93+
94+
it('should be able to startPolling', () => {
95+
spyOn(obsApollo, 'startPolling');
96+
97+
const arg = 200;
98+
obsQuery.startPolling(arg);
99+
100+
expect(obsApollo.startPolling).toHaveBeenCalledWith(arg);
101+
});
102+
103+
it('should be able to stopPolling', () => {
104+
spyOn(obsApollo, 'stopPolling');
105+
106+
obsQuery.stopPolling();
107+
108+
expect(obsApollo.stopPolling).toHaveBeenCalled();
109+
});
42110

43-
const res = new ApolloQueryObservable(obs).map((i) => i);
111+
it('should be able to fetchMore', () => {
112+
spyOn(obsApollo, 'fetchMore');
44113

114+
const arg = 200;
115+
obsQuery.fetchMore(arg);
45116

46-
expect(res['refetch']()).toEqual('refetch');
47-
expect(obs.refetch).toHaveBeenCalled();
117+
expect(obsApollo.fetchMore).toHaveBeenCalledWith(arg);
118+
});
48119
});
49120
});

0 commit comments

Comments
 (0)