Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Loading state stuck on true and network request is never made #1385

Closed
nlucero opened this issue Dec 6, 2017 · 36 comments
Closed

Loading state stuck on true and network request is never made #1385

nlucero opened this issue Dec 6, 2017 · 36 comments

Comments

@nlucero
Copy link

nlucero commented Dec 6, 2017

I'm having an issue using the graphql HOC. I'm receiving via props on my wrapped component an object with the variables that are used on the graphql query (let's call it the filters object). When an error occurs on the API, the data { error } prop is injected correctly into my wrapped component and contains the error that comes on the response. But, after this, when the query is re-run with different variables (due to the filters object being updated), graphql makes NO NETWORK REQUEST at all, and the data { loading } prop is stuck on true forever.

I've even tried setting the errorPolicy to all. But in that case, the data { error } prop always come as undefined (even when there are errors on the API response). Not sure if this is intended or another bug 😛

Here is my wrapped component (I'm using recompose):

const withData = graphql(caseInfoQuery, {
  options: ({ filters }) => ({
    variables: filters
  })
});

const enhance = compose(
  withData,
  defaultProps({ data: {} }),
  withProps(({ filters, data: { cases, loading, error } }) => ({
    cases,
    loading
  }))
);

export default enhance(MyDataTable);

I'm using these package versions:

"dependencies": {
    "apollo-cache-inmemory": "^1.1.3",
    "apollo-client": "^2.1.0",
    "apollo-link": "^1.0.5",
    "apollo-link-error": "^1.0.2",
    "apollo-link-http": "^1.3.0",
    ...
}
@nlucero
Copy link
Author

nlucero commented Dec 6, 2017

I created the same issue on the apollo-client repo, but I think it belongs here.

@nfantone
Copy link

nfantone commented Dec 6, 2017

@jbaxleyiii I've been doing some digging and I think this is related to the queryObservable object on the HOC. On initial load, when requesting the currentResult(), errors are returned as expected. However, after the first error (network or GraphQL originated), that method always returns:

{data:{}, loading:true, networkStatus:1, partial:true}

It seems like after erroring, the query observable stream doesn't update any more and keeps emitting the same value over and over again (or doesn't emit any new ones).

@nfantone
Copy link

nfantone commented Dec 6, 2017

I can also confirm that this is still happening on master code from both this component and apollo-client.

@mfurniss
Copy link

I'm having exactly this issue. After a data error, if the same query is reissued then the data loading flag never clears. apollo-client 2.1.0 with react-apollo 2.0.4

@nfantone
Copy link

At this point, and from what we could gather, this seems to me like a serious issue that pretty much renders the component unusable under general circumstances. Input from collaborators would be really nice. @peggyrayzis?

@prawana-perera
Copy link

See this doco: https://www.apollographql.com/docs/react/basics/queries.html#graphql-query-data-networkStatus

data.networkStatus is useful if you want to display a different loading indicator (or no indicator at all) depending on your network status as it provides a more detailed view into the state of a network request on your component than data.loading does

Does that mean its better to use this instead?

@nfantone
Copy link

@prawana-perera It's better if you want your components to behave differently according to which HTTP status you get back from the endpoint. Still, the data.loading attribute should update accordingly, which is not currently. I don't see data.networkStatus as a replacement.

@fracmak
Copy link
Contributor

fracmak commented Jan 22, 2018

So I've dug into this problem and here's my take on it. This is not actually a bug in the react-apollo code, but in the ObservableQuery code. When an error occurs, the observable query calls cleanup code which tears down the observer, which then triggers the tearDownQuery() code here:

https://github.com/apollographql/apollo-client/blob/d4dc034f1a74a177a9187870b96ac6d397064774/packages/apollo-client/src/core/ObservableQuery.ts#L538-L544

Which is fine cause the next call to update the query sets up another observer (after first setting up the query). So based on this PR: https://github.com/apollographql/apollo-client/pull/1154/files it shouldn't immediately fire a query when there are no observers, instead preferring to defer them until an observer appears.

Again, no problem. The bug appears when the observer is attached and it tries to fire off another query. This code: https://github.com/apollographql/apollo-client/blob/d4dc034f1a74a177a9187870b96ac6d397064774/packages/apollo-client/src/core/ObservableQuery.ts#L532-L533 remembers the last query and error and returns them to the newly set up observer resulting in incorrect results being sent to the observer, and resolving the internal promise so the real query results are dropped.

My solution is to tear down the last error and last result when the last observer dissapears. But again, this is a bug in the apollo client, not react-apollo

@fracmak
Copy link
Contributor

fracmak commented Jan 22, 2018

Or probably even better, setVariables should clear the lastResult and lastError

@lluzak
Copy link

lluzak commented Jan 22, 2018

This PR should has fix it #1531.

@nnnoel
Copy link

nnnoel commented Jan 30, 2018

This is still a problem for me, using apollo-client 2.2.1 and react-apollo 2.1.0-beta.0. @fracmak is dead on here. The ObservableQuery logic unsubscribes the observable when lastResult and lastError are present, so any queries that have any previous errors (in my case, a query with a network-only policy) won't update correctly whenever my component, using graphql hoc, remounts.

As @fracmak suggested, removing these lines https://github.com/apollographql/apollo-client/blob/d4dc034f1a74a177a9187870b96ac6d397064774/packages/apollo-client/src/core/ObservableQuery.ts#L532-L533 fixes this for me.

@nfantone
Copy link

@fracmak Care to point out the same thing over at the apollo-client repo?

@viggyfresh
Copy link

Same issue as all the above commenters, with apollo-client 2.2.2, react-apollo 2.1.0-beta.0, apollo-cache-inmemory 1.1.7. Manually removing the lines:

if (observer.next && this.lastResult)
    observer.next(this.lastResult);
if (observer.error && this.lastError)
    observer.error(this.lastError);

in my locally npm installed ObservableQuery.js appears to fix the issue.

@mxmzb
Copy link

mxmzb commented Mar 23, 2018

I'm also experiencing this issue on apollo-client 2.2.7 and react-apollo 2.1.0 and @viggyfresh's fix won't even work. I am slowly getting the impression I have built a related bug somewhere else in my application.

@luccasmaso
Copy link

react-apollo@^2.1.0 fixes for me

@ynuska
Copy link

ynuska commented Mar 26, 2018

@luccasmaso what is your "apollo-client" package version ? thx!

@luccasmaso
Copy link

@ynuska apollo-client@^2.2.8

@ynuska
Copy link

ynuska commented Mar 26, 2018

thx! I've updated to react-apollo@^2.1.0 and now I get this error Cannot find module 'apollo-client' from 'react-apollo.umd.js'. Has todo with jest, I will update now also apollo-client package.

@hwillson
Copy link
Member

Hi all - this should be fixed in newer versions of react-apollo. If you're still encountering this issue after updating to a current version (2.1.4 as of today), please post back and let us know. Thanks!

@chevalam
Copy link

Hey @hwillson , I'm still facing this issue. Sometimes the loading prop stays stuck on true and I can't see any outgoing requests nor requests hitting the backend. I am using react-apollo v^2.1.4 and apollo-client v^2.3.1

@hwillson
Copy link
Member

Thanks @chevalam - re-opening to investigate.

@hwillson hwillson reopened this May 25, 2018
@heysailor
Copy link

heysailor commented Jun 17, 2018

And similarly with [email protected], using the example get-started in the Apollo docs.

@townmulti
Copy link

+1

@arrygoo
Copy link

arrygoo commented Jul 12, 2018

+1 Facing this in AppSync now

@andrroy
Copy link

andrroy commented Sep 21, 2018

+1, having this issue in [email protected]

@andrroy
Copy link

andrroy commented Sep 21, 2018

Update: This happens if i create the following container:

import { compose, graphql } from 'react-apollo';

const query1 = graphql(ACTIVE_ORDERS_QUERY, {
  name: 'q1Data',
  props: ({ q1Data }, ownProps) => {
    return { ...q1Data, ...ownProps };
  },
});

const query2 = graphql(ACTIVE_ORDERS_QUERY, {
    name: 'q2Data',
    props: ({ q2Data }, ownProps) => {
      return { ...q2Data, ...ownProps };
    },
});

export default compose(
    query1,
    query2,
)(MyComponent);

If I remove the props key from both queries, loading is set to false:

import { compose, graphql } from 'react-apollo';

const query1 = graphql(ACTIVE_ORDERS_QUERY, {
  name: 'q1Data',
//   props: ({ q1Data }, ownProps) => {
//     return { ...q1Data, ...ownProps };
//   },
});

const query2 = graphql(ACTIVE_ORDERS_QUERY, {
    name: 'q2Data',
    // props: ({ q2Data }, ownProps) => {
    //   return { ...q2Data, ...ownProps };
    // },
});

export default compose(
    query1,
    query2,
)(MyComponent);

I have tried setting notifyOnNetworkStatusChange to true, and have double checked that networkStatus matches the loading prop

@hwillson Please let me know if you need any more info, or if it is something I can do to help!

@sapkra
Copy link

sapkra commented Nov 5, 2018

Still not fixed!

I'm using

"apollo-client": "^2.4.5",
"react-apollo": "^2.2.4",

and I also tried react-apollo: 2.3.0-beta.1

@ckj
Copy link

ckj commented Nov 5, 2018

I'm using

"apollo-client": "^2.4.5",
"react-apollo": "^2.2.4",

Same. Is there a workaround?

@sapkra
Copy link

sapkra commented Nov 5, 2018

I figured out that the only things they are not working are the queries they want to get data from the server. All the @client queries are working fine.

Query-> broken
graphql()()-> broken
withApollo()-> working

So I have to do the following now because withApollo is the only method which is working. I hope it will be fixed soon so that my code will be less complex.

class UserContainer extends React.Component {
  constructor() {
    super();

    this.state = {
      me: null,
    };
  }

  componentDidMount() {
    const { client, authToken } = this.props;

    client
      .query({
        query: getMe,
        ...createAuthContext(authToken),
      })
      .then(({ data: { me } }) => this.setState({ me }));
  }

  render() {
    const { me } = this.state;

    return me ? <User user={me} /> : null;
  }
}

export default compose(
  withApollo,
  graphql(getAuthToken, {
    props: ({ data: { authToken } }) => ({
      authToken: authToken.token,
    }),
  }),
)(UserContainer);

@sapkra
Copy link

sapkra commented Dec 2, 2018

@ckj Have you found a real solution for this problem?

@ckj
Copy link

ckj commented Dec 3, 2018

@sapkra In my situation I was using multiple enhancers on a component without utilizing react-apollo's compose function. Once I added it in, the problem seems to have went away 🤞.

@sapkra
Copy link

sapkra commented Dec 14, 2018

I figured out a solution for this problem! I forgot to add the following part before my component is rendered.

I just added this to my component and the problem was solved. You can find an example in the README of this repository.

if (loading) return 'Loading...';
if (error) return `Error! ${error.message}`;

The reason why it didn't triggered the request is that the javascript crashed after trying to render the component with no data & loading: true. You have to catch the loading state and possible errors.

This example is missing in the docs so someone can easely get this error.

@rosskevin
Copy link
Contributor

Is this still a problem or can it be closed? It is unclear to me from the history.

@sapkra
Copy link

sapkra commented Dec 27, 2018

I think it can be closed - when someone has still this problem he/she can create a new issue.
The history of this ticket catches more than one problem so in a new ticket the actual problem will be much more clear.

@ducarroz
Copy link

ducarroz commented Jun 4, 2019

I am still experiencing this issue using the latest version of apollo client, I have open issue #3090

@samthomson
Copy link

I solved this ("apollo-client": "^2.6.4" and "react-apollo": "^3.0.0") by passing the notifyOnNetworkStatusChange: true, option (in the options param of
graphql HOC).

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