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

watchQuery doesn't get the new result after a mutation #144

Closed
amannn opened this issue Apr 23, 2016 · 16 comments
Closed

watchQuery doesn't get the new result after a mutation #144

amannn opened this issue Apr 23, 2016 · 16 comments
Assignees

Comments

@amannn
Copy link
Contributor

amannn commented Apr 23, 2016

I'm experimenting a bit with mutations. I've noticed that in the React docs it's mentioned that it's a typical pattern to refetch() data after a mutation succeeded.

However the docs for watchQuery say that when a mutation happens, watchQuery will return the updated result automatically.

I first tried this with the regular apollo-client and later with the React integration, but I couldn't get the UI to update based on a mutation without calling refetch.

Are there some boundaries for what can be automatically re-fetched based on mutations and what not? I'd also have a repo which shows the issue if that helps.

@stubailo
Copy link
Contributor

Yeah I think this is something that isn't quite working yet - having more automated fetching after a mutation is a short term goal but for now you pretty much need to use 'refetch'.

@amannn
Copy link
Contributor Author

amannn commented Apr 23, 2016

Thanks for the quick reply!

Btw. here is the repo if you want to see the bug.

All mutations now call refetch so the data stays as much up-to-date as possible. But there's still the issue if you change the title of an article and navigate back to home, the title of the article in the list won't have changed (even though forceFetch is turned on).

This is just my personal playground, so I don't need a solution anytime soon. I just wanted to point this out, if you don't already know about this.

@stubailo
Copy link
Contributor

I'll look into that code soon! Perhaps there is a bug somewhere :]

@Poincare
Copy link
Contributor

Poincare commented May 24, 2016

Now that we can transform queries to add typenames (as of 0.3.12), we can solve this problem. To add the query transformation:

import { addTypenameToSelectionSet } from 'apollo-client/queries/queryTransform';
const client = new ApolloClient({
  ...
  queryTransformer: addTypenameToSelectionSet,
  ...
});

This adds the __typename field to every SelectionSet within each query and if we add an id field to a query (e.g. when asking for a user's first and last name, we also ask for an id), the state change within Redux caused by the result of the mutation should lead to updated data.

@stubailo
Copy link
Contributor

For more context, here's the full PR for adding that change to GitHunt: https://github.com/apollostack/GitHunt/pull/4

@amannn
Copy link
Contributor Author

amannn commented May 28, 2016

Thanks for the info! I'll have a look at it soon to see if I can fix the issue in my test app.

@kokjinsam
Copy link

@Poincare, does the new update mean that we don't to refetch after a mutation? I can't seem to get it work.

@Poincare
Copy link
Contributor

Poincare commented Jun 1, 2016

If the result of a query is uniquely identifiable with the query itself (e.g. using some kind of ID field and supplying dataIdFromObject to ApolloClient). If you check out the GitHunt PR referenced by @stubailo, it concatenates __typename with id in order to get a unique identifier for each Entry.
As a rule of thumb, if you have a unique identifier within your query, the refetch shouldn't be needed.

I'm sorry this is a bit confusing at the moment - we should have better docs on this pretty soon. In this meantime, if you could provide some more information as to the query you are firing, that would be very helpful.

@kokjinsam
Copy link

@Poincare , thank you for your response. Actually, it's working. I can see updated result after mutation in the store. But my UI is not updating. Is this the correct behavior?

Here's how I query the data and here's the mutation

@helfer
Copy link
Contributor

helfer commented Jun 3, 2016

@sammkj: Does the updated result replace the data that was there before? I.e. is the result stored under the same key?

@kokjinsam
Copy link

@helfer, here's what I got before the mutation in my store:

todo1

And here's what I got after mutation:
todo2-2

@helfer
Copy link
Contributor

helfer commented Jun 3, 2016

@sammkj Is your mutation by any chance inserting a new element?

In that case this is a known limitation that a list query run previously will not reflect that change, because we have no way of knowing whether that new element belongs to that list or not without rerunning the list query.

A workaround is to return the root query object from the mutation and rerun the original list query to force the list on the UI to update. We're thinking about better ways to do see-your-own-writes for this kind of mutation.

@kokjinsam
Copy link

Yes, the mutation inserts a new todo. So does that mean that the new update only work if I have mutation that updates data? If that's case, I can't get it work either. My UI is not updating.

Just out of curiosity, I kinda expect that this would work somewhat similar to Redux state. As in if I update the store and the component that subscribes to the store will get updated automatically.

@helfer
Copy link
Contributor

helfer commented Jun 4, 2016

If the updated object is returned by your mutation (i.e. it is in the selection set), then the redux store will update and your component will update as well. If your component displays a list, then that particular list must be updated in the redux store. That will only happen if you query for it again with the same arguments so it ends up in the same place in the redux store.

This is because your component subscribes to a particular list in the redux store. If a new item is created and returned on its own, Apollo Client currently has no way of knowing where to put it in the list, thus you have to ask for the whole list again (you could get away with just the ids, I think), so it gets overwritten.

@amannn
Copy link
Contributor Author

amannn commented Jun 12, 2016

I just tried the new normalization feature out in my app and updating data now works as expected – great job! :)

I totally understand that creations don't result into updating lists, as the client doesn't know how that list is sorted and the server should be the only source of truth for this. So I guess a re-fetch always makes sense if the UI is expected to show the result immediately. This could maybe be improved with realtime web socket connections if this is a common use case for an app (like Meteor always did it). Another idea would be to decouple the mutations from UI components, so there's a central place to define which lists need to be re-fetched when a specific mutation occurs. But I think this can be solved outside of Apollo in user land.

One thing I was wondering though, is if mutations that result in a deletion of an entity could result into an updated UI immediately. In a redux app I'm working on, I got this working by removing the entity from the store when its deleted. When a list re-renders that the entity used to be part of, it's not shown anymore since when the data for the list is prepared, the entity isn't found anymore and thus left out. I'm not quite sure how this could work with GraphQL though, since there's no special DELETE mutation and mutations can just return updated data (which can't specify if the entity got removed as far as I know). Have you thought about that by chance?

I close this issue, as my original problem is now solved.

@amannn amannn closed this as completed Jun 12, 2016
@stubailo
Copy link
Contributor

Yeah we have a lot of thoughts about how mutation results should work, but as you mentioned it can be quite complex. Hopefully in the next month or so we can provide some solutions.

jbaxleyiii pushed a commit that referenced this issue Oct 17, 2017
jbaxleyiii pushed a commit that referenced this issue Oct 18, 2017
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 17, 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

No branches or pull requests

5 participants