graphql-ruby
graphql-ruby copied to clipboard
Observer is null for relaySubscriptionHandler
Hi @rmosolgo, currently (if I don't get it terribly wrong), createRelaySubscriptionHandler
doens't pass an observer to Relay Network layer, resulting in an Uncaught TypeError: Cannot read property 'onNext' of undefined
Offending lines
received: function (payload) {
// When we get a response, send the update to `observer`
var result = payload.result;
if (result && result.errors) {
// What kind of error stuff belongs here?
observer.onError(result.errors);
}
else if (result) {
observer.onNext({ data: result.data });
}
if (!payload.more) {
// Subscription is finished
observer.onCompleted();
}
}
observer is undefined. Am I doing something wrong? If yes, maybe some additional comments in docs can be helpful (let me know if you accept PR) Thanks!
graphql
version: 1.10.5
rails
(or other framework): 6
graphql-batch
version: 0.5.4
react-relay
: 9.0.0
react-relay-network-modern
: ^4.2.0`
We're using intepreters, it happens with any query / subscription
GraphQL query
subscription NewMessageSubscription {
messageCreated {
id
}
}
We use react-relay-network-modern setup as follow:
const subscribeFn = createRelaySubscriptionHandler({
cable: consumer,
});
const network = new RelayNetworkLayer(
[
process.env.NODE_ENV === 'development' ? loggerMiddleware() : null,
process.env.NODE_ENV === 'development' ? errorMiddleware() : null,
process.env.NODE_ENV === 'development' ? perfMiddleware() : null,
],
{
subscribeFn,
},
);
const source = new RecordSource();
const store = new Store(source);
const environment = new Environment({
network,
store,
});
It looks like that function expects observer
to be given as an argument:
https://github.com/rmosolgo/graphql-ruby/blob/d1ca69a3daf93286c529e8fccb6e108c4370fb5b/javascript_client/src/subscriptions/createActionCableHandler.ts#L16
Could you please share the full error message and backtrace?
let me know if you accept PR
Yes.
Sure
TypeError: source.subscribe is not a function
at new Executor (RelayModernQueryExecutor.js:97)
at Object.execute (RelayModernQueryExecutor.js:48)
at RelayModernEnvironment.js:270
at _subscribe (RelayObservable.js:580)
at RelayObservable.subscribe (RelayObservable.js:281)
at RelayObservable.js:196
at _subscribe (RelayObservable.js:580)
at RelayObservable.subscribe (RelayObservable.js:281)
at RelayObservable.js:293
at _subscribe (RelayObservable.js:580) "
Since subscribeFn is passed to ReactRelayNetworkModern it may also be an issue with how this function is handled by this Network Layer https://github.com/relay-tools/react-relay-network-modern/blob/5cd2699d1418b72f5735c82f4f0dddf4fb9b2407/src/definition.js#L130
The function created by createActionCableHandler seems ok
export type SubscribeFunction = (
operation: ConcreteBatch,
variables: Variables,
cacheConfig: CacheConfig,
observer: any
) => RelayObservable<QueryPayload> | Disposable;
but observer can't be created with this function's options...
just came to report this, see also:
https://github.com/relay-tools/react-relay-network-modern/issues/95
i'm working on a pr locally as well.
I've run into this as well. @modosc have you been able to solve this?
I was having this error too with subscriptionFn in modern relay. The solution was to add a "subscribe"property , with a "dispose" property too, in the object I was returning in my function.
const setupSubscription = (
config: any,
variables: any,
cacheConfig: any,
observer: any
) => {
console.log('config: ', config, 'variables: ', variables, 'cacheConfig: ', cacheConfig, 'observer: ', observer);
const subscriptionClient = new SubscriptionClient(
'ws://localhost:3333/subscriptions',
{
reconnect: true,
connectionParams: {
authorization: localStorage.getItem('authToken')
},
lazy: true
},
);
const query = config.text;
const client = subscriptionClient.request({ query, variables });
console.log('client observable: ', client);
let subscription: any;
return {
subscribe: (observer: any) => {
console.log('observer: ', observer);
subscription = client.subscribe(observer);
observer.start(subscription);
},
dispose: () => {
subscription.unsubscribe();
},
};
}
Did anyone solve this? I'm having the same problem with the ActionCable subscription handler. Modifying the returned object to have a subscribe
property did not help.
Sorry, I'm not sure if this is still a problem 😖 If you run into this again, please open a new issue and we can investigate again!