Intended outcome:
I'd like to use the basic zen-observable methods like map and filter to pipe the results of a query through some transformations before subscribing to it.
apolloClient.watchQuery({ query })
.map(result => transformResult(result))
.subscribe(console.log);
The docs say "Refer to the zen-observable documentation for additional context and API options." — I read that as the standard zen-observable API should be available and cooperate with the ObservableQuery API.
Actual outcome:
Calling any of the above methods cause runtime errors that look like:
/sandbox/node_modules/apollo-client/bundle.umd.js:146
_this.variables = options.variables || {};
^
TypeError: Cannot read property 'variables' of undefined
The actual line of code where the error occurs is here.
How to reproduce the issue:
Reproduction:
https://codesandbox.io/embed/apollo-client-observable-query-map-509cw
zen-observable seems to support subclassing, but it assumes that the subclass constructor has the same signature. This creates two problems:
.map creates a new ObservableQuery, it doesn't know about the constructor's queryManager, options, and shouldSubscribe arguments.new ObservableQuery(fn), the new observable returned from .map doesn't have a query manager so ObservableQuery's methods like refetch do not work.Versions
Okay, quick note here:
ObservableQuery implementation. I'm hoping to add those and submit a PR soon.ObservableQuery doesn't accept an observer as its first argument, I'm not sureextension is the right way to go here. To your point (https://github.com/zenparsing/zen-observable/blob/f63849a8c60af5d514efc8e9d6138d8273c49ad6/src/Observable.js#L252-L254) isn't expecting anything but an observer.To add some more color to this ticket: I _can_ use RxJS's from to get access to map and friends:
const { from } = require('rxjs');
const { map } = require('rxjs/operators');
from(apolloClient.watchQuery({ query }))
.pipe(map(transformResult))
.subscribe(console.log);
So that's a nice, albeit heavy, solution. It's still problematic that I lose access to the ObservableQuery API tho:
from(apolloClient.watchQuery({ query, variables }))
.pipe(map(transformResult))
.refetch(newVariables); // TypeError: mapped.refetch is not a function
Can I pick up this bug?
@vilvaathibanpb Please feel free to give it a go! We've been discussing how best to solve this one, but have been focused on the next version of Apollo Client. If we're going to address it, we'll need to fix it in the 3.x version at this point.
@jhampton Sure, I will give a try on this :)
One workaround I just found:
import Observable from 'zen-observable';
Observable.from(apolloClient.watchQuery({ query }))
.map(result => transformResult(result))
.subscribe(console.log);
This removes the ObservableQuery API, so if you need refetch, you can do:
const original = apolloClient.watchQuery({ query });
const transformed = Observable.from(original)
.map(result => transformResult(result));
transformed.subscribe(console.log);
original.refetch({ some: 'variables' });
What works for me:
````js
import Observable from 'zen-observable';
// client built from from 'apollo-client' not 'apollo-boost';
const obs = client.subscribe({
query: gql(queryString),
variables,
...opts
});
const obs2 = Observable.from(obs).map((e) => transform(e));
obs2.subscribe({
next,
error,
complete
});
````
@hwillson Do we have a sense if this might be address in AC3?
Most helpful comment
What works for me:
````js
import Observable from 'zen-observable';
// client built from from 'apollo-client' not 'apollo-boost';
const obs = client.subscribe({
query: gql(queryString),
variables,
...opts
});
const obs2 = Observable.from(obs).map((e) => transform(e));
obs2.subscribe({
next,
error,
complete
});
````