Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data disappears between two queries of the same type. UI updates with empty props. #3928

Closed
coolov opened this issue Sep 18, 2018 · 8 comments

Comments

@coolov
Copy link

coolov commented Sep 18, 2018

I am using react-apollo and the <Query> component.

Intended outcome:
Execute two queries (A and B) in series over the same root field (article) and with a shared sub-query (image). There are fewer fields on the image sub-selection in query B than on image in query A. The image id changes upstream between the execution of the two queries, so the data responses will be slightly different for the two queries.

First query:

query A {
  article {
    id
    image {
      id 
      src
    }
  }
}

Later query (triggered after a user interaction):

query B {
  article {
    id
    title
    image {
      id   # This id has changed since query A was executed
    }
  }
}

The <Query> component that is subscribing to query A should either get updated with new data after B is completed, or ignore the data from B if it's inconsistent with A.

Actual outcome:
The query component that is subscribing to A is re-rendered without the data prop.

How to reproduce the issue:
https://codesandbox.io/s/0xl9v5znnw

Versions
"apollo-cache-inmemory": "1.2.10"
"apollo-client": "2.4.2"
"react-apollo": "2.1.11"

Possibly related
#3267
apollographql/react-apollo#2003

@jonerer
Copy link

jonerer commented Sep 24, 2018

Any workaround for this? Does anyone know a previous version that works? I'm just getting into using apollo/graphql and it doesn't work, so I don't know what previous versions were fine.

@oxy88
Copy link

oxy88 commented Sep 26, 2018

This is a serious problem

@quolpr
Copy link

quolpr commented Dec 9, 2018

Are there any workarounds? 😞

@hwillson
Copy link
Member

hwillson commented Jan 2, 2019

The solution to this is to set the React Apollo Query component partialRefetch prop to true. See the Query component API docs for more info.

@hwillson hwillson closed this as completed Jan 2, 2019
@KamalAman
Copy link

KamalAman commented Jan 18, 2019

Setting partialRefetch to true is not solution for all cases here, this only works if query B is a complete subset of query A or vice versa

First query:

query A {
  article {
    id
    image {
      id 
      src
    }
  }
}

Later query (triggered after a user interaction):

query B {
  article {
    id
    title
    image {
      id 
      somethingElse
    }
  }
}

partialRefetch will cause an infinite loop for queryA -> queryB -> partialRefetch queryA -> partialRefetch queryB -> partialRefetch queryA -> partialRefetch queryB-> partialRefetch queryA -> partialRefetch queryB -> partialRefetch queryA -> partialRefetch queryB.....

@joshjg
Copy link
Contributor

joshjg commented Jun 3, 2019

I've run into a similar issue with queries like these:

query A {
  article {
    image {
      src
    }
  }
}
query B {
  article {
    id
    title
    body
  }
}

Notice that query B requests an id field, while query A does not. Query A will be cached under a key like ROOT_QUERY.article, while query B will be under Article:{id}. Depending on the order these queries are resolved, the results of query A can get obliterated from the cache.

@helfer
Copy link
Contributor

helfer commented Feb 7, 2020

@KamalAman I'm a bit late to the party here, but are you sure the scenario you described would actually happen? Last I know, Apollo Client will merge objects in the cache, so the only case in which your loop would happen is if the image associated with your article changes between each query.

In any case, I think there is no "perfect" solution here. In some cases, even merging object fields in the cache may be undesirable. However, in most cases I think partialRefetch will do what people expect, and it won't lead to any loops. Following the principle of least surprise, it might make sense to enable it by default, the logic being that most people are more surprised when their query suddenly fails in production, than if there's an occasional extra query being made against their server.

@joshjg
Copy link
Contributor

joshjg commented Mar 8, 2020

@helfer In my mind partialRefetch makes sense as a default if issues like these cannot be mitigated in another way. However, it would be helpful to get some feedback when a scenario like I posted above occurs. A console warning at the least. Currently it fails silently.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants