Apollo-client: Query with `fetchPolicy: 'cache-only'` is not updatable via `updateQueries`

Created on 5 Apr 2017  路  12Comments  路  Source: apollographql/apollo-client

I have a query Sale that I don't want to initially fetch and a mutation OpenSale with:

      updateQueries: {
        Sale: (prev, { mutationResult }) => console.log('test'),
      },

Intended outcome:
Console prints 'test'

Actual outcome:
Nothing happens

How to reproduce the issue:
Create a query with fetchPolicy: 'cache-only', try to update it in a mutation with updateQueries.

I'm trying to upgrade to 1.0.2 from 0.8.6. Previously I had noFetch: true and everything worked fine. Is it an expected behavior in 1.x or a bug?

All 12 comments

Removing updateQueries (so Apollo would perform update automatically) doesn't help either, newly received object is not shown, but I can see it in Apollo store (state.apollo.data):
image

just not on the page.

@Dattaya what framework-specific lib are you using, if any? react-apollo?

@Dattaya Thanks for the repro! Quick question: does the query error initially because there's nothing in the store? If not, what is the result that you get when running it the first time (before updateQueries).

@thebigredgeek, react-apollo.
@helfer, no errors, and no result from the query as expected (loading: false, error: undefined, person object in data is missing completely). This is what I'm trying to achieve: I want to fetch data in a mutation (because the DB is going to be affected), so the query has the 'cache-only' fetch policy and does nothing, its sole purpose is to be updated by the mutation.

Forgot to mention that previously it would work fine only if the mutation call was wrapped in setTimeout; I was fine with a hack as apollo-client was at the aplha stage, but maybe I'm misusing the library and not supposed to solve this task the way I did?

@Dattaya sorry this slipped from my radar. I'll look into it again shortly.

@Dattaya I can run your reproduction, but it doesn't actually seem to demonstrate anything because there are no instructions included, and no description of what's not happening that should be happening. Could you add that so I can look into it?

Looking at this again, this behavior is actually intended. If the query result is not in the store, updateQueries will not run. This is so that the data you get in the updateQueries function stays predictable. If you want to update a subset of that data, or just write data to the store, I recommend using update, which is much more flexible.

@helfer, thanks for your answer and thanks for keeping Apollo awesome.

If the query result is not in the store, updateQueries will not run

makes sense

I recommend using update, which is much more flexible.

I tried it too with no success and now I know why. The query initially receives id from react-router in the form of a string, but in writeQuery for the purpose of testing I wrote the value by hand as a number like so:

        proxy.writeQuery({
          query: query,
          variables: { id: 1 },
          data: {
            sale: { ...openSale },
          }
        });

That's why the result didn't show up on the page.

Is it normal that Apollo does not normalize variables or ID type is not supposed to be normalized to a string when it is a number? If that's not expected I can create a new issue with a reproduction case.

@Dattya yeah, that would definitely explain it! Apollo doesn't coerce any variables you give it. Since we don't have the schema on the client, so we can't even check if they fit the definition. I can see how that would be useful though, so I'm thinking about adding the option to put some more schema information in the client in the future to be able to do validation etc. with it.

so we can't even check if they fit the definition

I thought you can get this information from the beginning of a query: query Sale($id: >>ID!<<) { ?

You're right, we could check what you pass against the definition in the query. That might be useful for client-side updates. What we can't actually check is if the variables are of the correct type in the place where you use them.

I don't think we want to get into the variable coercion business, but it's good to know that we could, if we wanted to 馃榾

Was this page helpful?
0 / 5 - 0 ratings