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

RxJS support #430

Closed
kamilkisiela opened this issue Jul 20, 2016 · 14 comments
Closed

RxJS support #430

kamilkisiela opened this issue Jul 20, 2016 · 14 comments
Assignees

Comments

@kamilkisiela
Copy link
Contributor

kamilkisiela commented Jul 20, 2016

Here's an implementation of QueryObservable that works with RxJS.


import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/from';

const origin = client.watchQuery(options); // QueryObservable
const obs = Observable.from(origin);

origin.refetch(); // works
obs.refetch(); // refetch is undefined
obs.ish.refetch(); // works (it should) because `ish` is a reference to `origin`

To solve that problem I created a custom observable called ApolloQueryObservable that extends Observable from RxJS.

QueryObservable is saved under apollo property. This way I could create methods like refetch(), startPolling(), stopPolling(). Every method uses ApolloQueryObservable.apollo to call specific method.


import 'rxjs';
import { ApolloQueryObservable } from 'angular2-apollo';

const origin = client.watchQuery(options); // QueryObservable
const obs = new ApolloQueryObservable(origin);

origin.refetch(); // works
obs.refetch(); // works

obs.map(customMapFunction).refetch() // refetch is undefined

As you can see, it still won't work with operators. Here's why.

Every operator uses Observable.lift() method, for example map().

Observable.lift() creates new Observable, then assigns the current observable under source property. Here the moment where our custom methods (refetch etc) are being dropped.

I solved this by overwriting lift() method.

Now, the lift() method creates a new instance of ApolloQueryObservable instead of Observable, and passes the QueryObservable from apollo property in the constructor.

Every operator returns now ApolloQueryObservable.

import 'rxjs';
import { ApolloQueryObservable } from 'angular2-apollo';

const origin = client.watchQuery(options); // QueryObservable
const obs = new ApolloQueryObservable(origin);

origin.refetch(); // works
obs.refetch(); // works

obs.map(customMapFunction).refetch() // works

Problem with subscribe method

An example

import 'rxjs';
import { ApolloQueryObservable } from 'angular2-apollo';

const origin = client.watchQuery(options); // QueryObservable
const obs = new ApolloQueryObservable(origin);

obs.subscribe() // an error

It happens because there is no _subscription method inside the ApolloQueryObservable.

Even if we add one, we still need to subscibe to the QueryObservable (this.apollo).

I solved this here.

So now we can subscribe to an Observable at any point.

import 'rxjs';
import { ApolloQueryObservable } from 'angular2-apollo';

const origin = client.watchQuery(options); // QueryObservable
const obs = new ApolloQueryObservable(origin);

obs.map(result => result.data).subscribe(data => this.data = data);

I was thinking about moving this ApolloQueryObservable (in different name, whatever) to ApolloClient, because it's not angular2 specific and will help a lot of people, I think.

@kamilkisiela
Copy link
Contributor Author

Related:

@kamilkisiela
Copy link
Contributor Author

@stubailo @Urigo I think I did it. Take a look at this project https://github.com/kamilkisiela/apollo-rx-observable

@kamilkisiela
Copy link
Contributor Author

Of course we can move it under apollostack organisation as a separate package or even use it in apollo-client as one of the exported things.

@kamilkisiela kamilkisiela self-assigned this Aug 11, 2016
@kamilkisiela
Copy link
Contributor Author

angular2-apollo with support for RxJS has been released (v0.4.2)

@kamilkisiela
Copy link
Contributor Author

Killer feature for angular2-apollo that uses variable of a query as Observable.

kamilkisiela/apollo-angular#64

@kamilkisiela
Copy link
Contributor Author

ApolloClient + RxJS - proposal

@kamilkisiela
Copy link
Contributor Author

For more: apollo-client-rxjs

@manuelfink
Copy link

manuelfink commented Jan 1, 2017

@kamilkisiela @stubailo, what happened to this. is this part of apollo-client? I'm haveing trouble with rxjs forkJoin #1109

@kamilkisiela
Copy link
Contributor Author

We didn't want to include it in apollo-client but we needed this in Angular so Uri and I decided to create another package called apollo-client-rxjs, this way you can use apollo-client with rxjs even outside angular :)

@manuelfink
Copy link

so you'll keep to maintain to builds of apollo-client in future?

Why you decided to keep it seperate? Wouldn't it make sense to include in the main library and extend base library. AOT building and three shaking should avoid bundle size increase, so I think it should not be a big issue, but threes and functionality stay in sync?

@kamilkisiela
Copy link
Contributor Author

@manuelfink

so you'll keep to maintain to builds of apollo-client in future?

The apollo-client-rxjs is not a copy of the apollo-client, it's an extension. So whenever apollo-client updates the extensions is up to date.

Why you decided to keep it seperate? Wouldn't it make sense to include in the main library and extend base library. AOT building and three shaking should avoid bundle size increase, so I think it should not be a big issue

First of all. Not everyone uses tree-shaking. A lot of people use just the browserify, if I would include RxJS related things inside the apollo-client it will dramatically increase size of the package.

threes and functionality stay in sync

As I said, those are two separate packages. The apollo-client-rxjs has the apollo-client as a dependency. There's no duplication, there's no need to keep them in sync when it comes to tree-shaking.

To sum it up. Maybe in the future they will decide to include RxJS inside apollo-client but we can't wait for it, so the only solution was to create an extension that allows that. I could include these features in angular2-apollo but with an extra package, we open a space for other frameworks that want to use Apollo with RxJS.

@somombo
Copy link

somombo commented Jan 13, 2017

@kamilkisiela Hi, is there a chance that apollo-client-rxjs will be added as a separate repo in the apollostack org?

Great job on this by the way! Excited about trying it out in Angular

@kamilkisiela
Copy link
Contributor Author

@somombo But why? :) Maybe someday apollo-client will be using RxJS so I can deprecate apollo-client-rxjs.

Thanks and enjoy angular2-apollo!

@somombo
Copy link

somombo commented Jan 13, 2017

@kamilkisiela Oh I just figured it might get a little better visibility for the community.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants