apollo-client icon indicating copy to clipboard operation
apollo-client copied to clipboard

subscribeToMore is undefined on React Native

Open noghartt opened this issue 3 years ago • 1 comments

Intended outcome:

I'm using useQuery hook with subscribeToMore function in my App. Is something like it:

const { subscribeToMore } = useQuery(GET_QUERY);

useEffect(() => {
  subscribeToMore({
    // do something here...
  })
}, [subscribeToMore]);

But when I made a hot reload on my App, this cause a log error that alert me of an issue. I tried to use InteractionManger and useLayoutEffect to fix this, but I was unsuccessful. I tested some solutions on other issues but I was not successful either.

Actual outcome:

When I made a hot reload on my App, an error log appears with this message:

TypeError: TaskQueue: Error with task : undefined is not an object (evaluating '_this.currentObservable.query.subscribeToMore')
Screenshot of Error Log

How to reproduce the issue:

I don't know if I'm doing something wrong or if it's really a bug, so I believe that if you use subscribeToMore and perform a hot reload, you can reproduce the bug.

Versions

  System:
    OS: Linux 5.11 Arch Linux
  Binaries:
    Node: 14.16.0 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 6.14.11 - /usr/local/bin/npm
  Browsers:
    Firefox: 87.0
  npmPackages:
    react: 16.13.1
    react-native: 0.63.4
    @apollo/react-hooks: ^3.1.4 => 3.1.5 
    @apollo/react-testing: ^3.1.4 => 3.1.4 
    apollo-cache-inmemory: ^1.6.5 => 1.6.6 
    apollo-client: ^2.6.8 => 2.6.10 
    apollo-link: ^1.2.14 => 1.2.14 
    apollo-link-context: ^1.0.20 => 1.0.20 
    apollo-link-ws: ^1.0.20 => 1.0.20 
    apollo-upload-client: ^13.0.0 => 13.0.0 
    apollo-utilities: ^1.3.4 => 1.3.4 

noghartt avatar Apr 12 '21 17:04 noghartt

This is my temporarily patch.

diff --git a/node_modules/@apollo/client/react/data/QueryData.js b/node_modules/@apollo/client/react/data/QueryData.js
index 9f306fd..8f7c3d2 100644
--- a/node_modules/@apollo/client/react/data/QueryData.js
+++ b/node_modules/@apollo/client/react/data/QueryData.js
@@ -70,7 +70,12 @@ var QueryData = (function (_super) {
             return result;
         };
         _this.obsRefetch = function (variables) { var _a; return (_a = _this.currentObservable) === null || _a === void 0 ? void 0 : _a.refetch(variables); };
-        _this.obsFetchMore = function (fetchMoreOptions) { return _this.currentObservable.fetchMore(fetchMoreOptions); };
+        _this.obsFetchMore = function (fetchMoreOptions) {
+            if (!_this.currentObservable) {
+                _this.initializeObservableQuery();
+            }
+            return _this.currentObservable.fetchMore(fetchMoreOptions);
+        };
         _this.obsUpdateQuery = function (mapFn) { return _this.currentObservable.updateQuery(mapFn); };
         _this.obsStartPolling = function (pollInterval) {
             var _a;
@@ -80,7 +85,13 @@ var QueryData = (function (_super) {
             var _a;
             (_a = _this.currentObservable) === null || _a === void 0 ? void 0 : _a.stopPolling();
         };
-        _this.obsSubscribeToMore = function (options) { return _this.currentObservable.subscribeToMore(options); };
+        _this.obsSubscribeToMore = function (options) {
+            if (!_this.currentObservable) {
+                _this.initializeObservableQuery();
+                _this.startQuerySubscription();
+            }
+            return _this.currentObservable.subscribeToMore(options);
+        };
         _this.onNewData = onNewData;
         return _this;
     }
diff --git a/node_modules/@apollo/client/react/data/data.cjs.js b/node_modules/@apollo/client/react/data/data.cjs.js
index 54db22d..d102718 100644
--- a/node_modules/@apollo/client/react/data/data.cjs.js
+++ b/node_modules/@apollo/client/react/data/data.cjs.js
@@ -349,7 +349,12 @@ var QueryData = (function (_super) {
             return result;
         };
         _this.obsRefetch = function (variables) { var _a; return (_a = _this.currentObservable) === null || _a === void 0 ? void 0 : _a.refetch(variables); };
-        _this.obsFetchMore = function (fetchMoreOptions) { return _this.currentObservable.fetchMore(fetchMoreOptions); };
+        _this.obsFetchMore = function (fetchMoreOptions) {
+            if (!_this.currentObservable) {
+                _this.initializeObservableQuery();
+            }
+            return _this.currentObservable.fetchMore(fetchMoreOptions);
+        };
         _this.obsUpdateQuery = function (mapFn) { return _this.currentObservable.updateQuery(mapFn); };
         _this.obsStartPolling = function (pollInterval) {
             var _a;
@@ -359,7 +364,13 @@ var QueryData = (function (_super) {
             var _a;
             (_a = _this.currentObservable) === null || _a === void 0 ? void 0 : _a.stopPolling();
         };
-        _this.obsSubscribeToMore = function (options) { return _this.currentObservable.subscribeToMore(options); };
+        _this.obsSubscribeToMore = function (options) {
+            if (!_this.currentObservable) {
+                _this.initializeObservableQuery();
+                _this.startQuerySubscription();
+            }
+            return _this.currentObservable.subscribeToMore(options);
+        };
         _this.onNewData = onNewData;
         return _this;
     }

I don't know why 'currentObservable' is disappeared. I think React is re-rendering hooks and cannot be keeping 'currentObservable' but I added some code to re-initialize(initializeObservableQuery, startQuerySubscription) and working good.

toy0605 avatar May 28 '21 10:05 toy0605