absinthe-graphql / absinthe-socket

Core JavaScript support for Absinthe WS-based operations
MIT License
149 stars 75 forks source link

function createSubscriber not compatible with relay 8.0.0? #44

Open Stanislav-Lapata opened 4 years ago

Stanislav-Lapata commented 4 years ago

react-relay: 8.0.0 @absinthe/socket-relay: 0.2.1

environment.js

import { Environment, Network, RecordSource, Store } from 'relay-runtime';
import { createFetcher, createSubscriber } from "@absinthe/socket-relay";
import * as withAbsintheSocket from "@absinthe/socket";
import {Socket as PhoenixSocket} from "phoenix";

const absintheSocket = withAbsintheSocket.create(
  new PhoenixSocket("ws://localhost:4000/graphql")
);

const environment = new Environment({
  network: Network.create(createFetcher(absintheSocket), createSubscriber(absintheSocket)),
  store: new Store(new RecordSource()),
});

export default environment;

component.js

import { requestSubscription } from 'react-relay';
import graphql from 'babel-plugin-relay/macro';

import environment from '../environment';

const tripFetchedSubscription = graphql`
  subscription SubscribeComponentSubscription {
    tripFetched {
      id
    }
  }
`;

function SubscribeComponent() {
  requestSubscription(
    environment
    {
      subscription: tripFetchedSubscription,
      variables: {},
      onCompleted: () => console.log('onCompleted'),
      onError: error => console.error(error),
    },
  );
  ...
};
TypeError: Cannot read property 'onError' of undefined
    at createSubscriber.js:49
    at Object.execute (RelayNetwork.js:31)
    at RelayModernEnvironment.js:264
    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)
    at RelayObservable.subscribe (RelayObservable.js:281)
    at requestSubscription (requestSubscription.js:50)
    at SubscribeComponent (SubscribeComponent.js:17)
    at renderWithHooks (react-dom.development.js:16260)
    at mountIndeterminateComponent (react-dom.development.js:18794)
    at beginWork$1 (react-dom.development.js:20162)
    at beginWork$$1 (react-dom.development.js:25756)
    at performUnitOfWork (react-dom.development.js:24695)
    at workLoopSync (react-dom.development.js:24671)
    at performSyncWorkOnRoot (react-dom.development.js:24270)
    at scheduleUpdateOnFiber (react-dom.development.js:23698)
    at updateContainer (react-dom.development.js:27103)
    at react-dom.development.js:27528
    at unbatchedUpdates (react-dom.development.js:24433)
    at legacyRenderSubtreeIntoContainer (react-dom.development.js:27527)
    at Object.render (react-dom.development.js:27608)
    at Module../src/index.js (index.js:8)
    at __webpack_require__ (bootstrap:785)
    at fn (bootstrap:150)
    at Object.1 (serviceWorker.js:137)
    at __webpack_require__ (bootstrap:785)
    at checkDeferredModules (bootstrap:45)
    at Array.webpackJsonpCallback [as push] (bootstrap:32)
    at main.chunk.js:1

Sorry I'm new to JS RelayNetwork expects a function with 3 arguments?

stephan83 commented 4 years ago

You can get it to work with something like this (works with relay 9):

import { Observable } from "relay-runtime";

// ...

const legacySubscribe = createSubscriber(withAbsintheSocket.create(socket));

// @absinthe/socket-relay is outdated so wrap it with a fix
const subscribe = (request, variables, cacheConfig) => {
  return Observable.create(sink => {
    legacySubscribe(request, variables, cacheConfig, {
      onNext: sink.next,
      onError: sink.error,
      onCompleted: sink.complete
    });
  });
};

const environment = new Environment({
  network: Network.create(fetchQuery, subscribe),
  store: new Store(new RecordSource())
});

export default environment;
redrabbit commented 4 years ago

@stephan83's solution fixed the problem for me (react-relay@9.1).

I had a bunch of TypeError as follow when using subscriptions with react-relay >= 6.0.0:

TypeError: undefined is not an object (evaluating '_ref3.onError')

Maybe @absinthe/socket-relay should implement @stephan83's solution or update RelayObservable's API to work with newer versions.