Apollo-client: New variables are not used after refetch(newVars)

Created on 11 Oct 2017  ·  36Comments  ·  Source: apollographql/apollo-client

Hello! I don't know how to make it better. Please help.
I use the function:

    async update() {
        let variables = {
            company: this.props.match.params.companyId,
            filter: this.filter, order: this.order, limit: this.pagiation.limit, offset: this.pagiation.offset
        };
        await this.props.refetch(variables);
    }

But I see in Network two queries and nothing happens.
The first one is right, but the second is the default data (like variables: { company: props.match.params.companyId, filter: {}, order: [], limit: 10, offset: 0 }). Why?

@ApolloReact.graphql(ApolloReact.gql"
    query Departments($company: ID!, $filter: DepartmentFilter!, $order: [DepartmentOrder], $limit: Int, $offset: Int) {
        company {
            get(id: $company) {
                id,
                name,
                color,
                departments {
                    list(filter: $filter, order: $order, limit: $limit, offset: $offset) {
                        departments {
                            id,
                            color,
                            name,
                            users {
                                id, avatar, username
                            },
                            tags {
                                name
                            },
                            date
                        },
                        count
                    }
                }
            }
        }
    }", {
    props: ({ ownProps, data: { loading, company, refetch } }) => ({
        company: company && company.get,
        departments: company && company.get && company.get.departments && company.get.departments.list.departments,
        count: company && company.get && company.get.departments && company.get.departments.list.count,
        loading: loading,
        refetch: refetch
    }),
    options: (props) => ({
        fetchPolicy: 'cache-and-network',
        variables: { company: props.match.params.companyId, filter: {}, order: [], limit: 10, offset: 0 }
    }),
})
has-reproduction ✔ confirmed 🐞 bug 🙏 help-wanted

Most helpful comment

I have updated the versions of apollo-client and other packages in the reproduction and this bug is still present.

Please see https://codesandbox.io/s/j3410pq2vv

  "dependencies": {
    "apollo-cache-inmemory": "1.6.2",
    "apollo-client": "2.6.3",
    "apollo-link-http": "1.5.15",
    "graphql": "14.4.2",
    "graphql-tag": "2.10.1",
    "react": "15.6.1",
    "react-apollo": "2.5.8",
    "react-dom": "15.6.1"
  }

@jbaxleyiii Could we revisit the original issue?

All 36 comments

But if I call console.log(await this.props.refetch(variables)); this is what I need, but I want to see it in props.

    async update() {
        let variables = {
            company: this.props.match.params.companyId,
            filter: this.filter, order: this.order, limit: this.pagiation.limit, offset: this.pagiation.offset
        };
        console.log(await this.props.refetch(variables));
    }

@makamekm what version of apollo client and react-apollo are you using?

"apollo-client": "1.9.3",
"react-apollo": "1.4.16"

I have also encountered the same behaviour.

When I call this.props.data.refetch(), without a variables argument, I see a network request for the query and this.props.data updating. However, if I call this.props.data.refetch({ stuff }), I still see a network request with the updated variables, but the corresponding props does not update. this.props.data.refetch({ stuff }) does return a Promise resolving to the results, though.

Using far older versions here.

    "apollo-client": "^1.2.2",
    "react-apollo": "^1.2.0",

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions to Apollo Client!

I'm still seeing this issue with latest apollo-client (2.0.3)

I'm encountering this problem in apollo client 2.1.0, and apollo-angular 1.0.0. The network request is sent, but the data is not used. I tried to debug into apollo client, and I found out that the network request is actually fulfilled after the update of the observable, which is weird.

I'm seeing this as well (2.0.3).

having the same issue , how to solve? props are not updated

Is this issue being solved?

Hello, is this issue being worked on?

I have the same problem, the refetch happens and shows on the network with the correct data. But by analyzing the response data, it displays the old data.
Anyone solved it?

Seeing this as well

Hopefully this is helpful: With the latest apollo-client release ([email protected]), you can call client.queryManager.clearStore() right before you refetch and your props should update correctly.

Edit: Note that you may cause the original query to be made in conjunction with the new query.

same error, tell me why.

Same error

@etripier didn't work fo me

Can anyone here provide a small runnable reproduction that clearly demonstrates this happening? Thanks!

@hwillson I am happy to have a reproduction that I believe covers the scenario described here: https://codesandbox.io/s/j3410pq2vv

My first guess was described in https://github.com/apollographql/apollo-client/issues/3948#issuecomment-433416971:

...For me this is happening because ObservableQuery.prototype.refetch is invoked once with the new variables, and then Query.prototype.componentWillReceiveProps calls ObservableQuery.prototype.updateQuery with the old variables. Since the Query component is involved, I believe this is related to react-apollo.

It seems like I was on the right track, because when I added fetchPolicy: 'cache-and-network' the bug reproduces. So putting all of that together, it appears this bug is caused by:

Given a query using fetchPolicy: 'cache-and-network'; when refetch is called with new variables, passing new props to the query component immediately after refetch has begun will cause the query to fire again with the old variables.

@pl12133 I'm seeing this same issue with fetchPolicy: "network-only". Variables passed into refetch are ignored.

I am seeing the same issue with
"apollo-client": "^2.4.6",
"react-apollo": "^2.3.1",

I need to retract my last comment. My issue was related to an interaction with react-navigation and apollo. Now that it is resolved I can confirm this variables issue does present itself when fetchPolicy: 'cache-and-network'. Switching to network-only does cause it to behave normally.

Changing the fetchPolicy from 'network-only' (or 'cache-and-network') to 'cache-first' which is the default fetchPolicy resolved my issue. Before it would trigger an extra fetch caused by Query.componentWillReceiveProps calling Query.updateQuery.

Options for fetchPolicy: https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-config-options-fetchPolicy

Reproduced with https://codesandbox.io/s/j3410pq2vv
Thanks @pl12133

I was facing the same problem, so as a workaround I'm able to pass new variables to refetch like this:

refetch({ ...variables, name: searchValue });

I'm experiencing a similar issue with refetch. I set some breakpoints and notice that Apollo will first run the query with the new variables. It will then trigger the original query to run, which uses the original props. This overwrites the new results with the old/original results. Then, if I trigger refetch again with new variables, it will perform the query with the new variables and NOT attempt to run the original query. I get the expected behavior on this second attempt.

It looks like refetch is not using the variables, but it does. It just runs the original query immediately after making it seem like only the original variables were used.

I'm using the HOC implementation with compose and graphql(). I'm also using the aws-appsync package, which seems to be using an older version of apollo-client (2.4.6). All of these could be factors in what I'm seeing.

@joebernard I'm having the same issue on 2.6.3 using the same method (HOCs but without aws-appsync). I'm currently getting around it by using withApollo() and querying via client.query() in place of where the refetch was.

@joebernard Thanks for reporting this. There hasn't been any activity here in quite some time, so we'll close this issue for now. Can you open a new issue reporting your issues with a reproduction for us to take a look into?

I have updated the versions of apollo-client and other packages in the reproduction and this bug is still present.

Please see https://codesandbox.io/s/j3410pq2vv

  "dependencies": {
    "apollo-cache-inmemory": "1.6.2",
    "apollo-client": "2.6.3",
    "apollo-link-http": "1.5.15",
    "graphql": "14.4.2",
    "graphql-tag": "2.10.1",
    "react": "15.6.1",
    "react-apollo": "2.5.8",
    "react-dom": "15.6.1"
  }

@jbaxleyiii Could we revisit the original issue?

I consider myself a React/Apollo novice, so what I'll describe as my solution should be taken with a grain of salt (and... my terminology may be off on some of these things). I'm guessing my use case is common (parent graphql HOCs w/ child graphql HOCs) and works successfully in a million other instances, so there's a good chance there's a nuanced detail that I'm unaware of that's specifically causing this problem.

Also, I'm still back on react-apollo v.2.2.4 / apollo-client v.2.4.5. Haven't acquainted myself with Hooks yet, so I don't know if they make HOCs unnecessary in newer versions.

I believe this same problem is also described in https://github.com/apollographql/react-apollo/issues/1929.

My problem:

I was using the graphql HOC in 2 components -- a ParentComponent and, within that component, a ChildComponent. The queries referenced for each had a fetch-policy of "network-only". The queries themselves were also different.

The ChildComponent is a paginated table that triggers a refetch when a page or rowsPerPage setting is changed. It has an initial set of variables for page / rowsPerPage. When a refetch is triggered, I pass in a new set of variables.

Console.log confirmed that, immediately post refetch, the new values were received correctly from the server. However, also immediately post refetch something else triggered a refresh of ChildComponent with the initial variables set again. ChildComponent never unmounted, so I was surprised that the initial values were ever set again (again, I'm a React novice, so there's a chance I don't understand the lifecycles correctly).

Either way, the net result was that my table would remain unchanged with the initial page of data.

What worked for me:

I swapped the graphql HOC out of the ParentComponent and replaced it with the withApollo HOC and accessed the client directly. I had to rework some of the initial loading/error presentation logic, but the result was that my ChildComponent was no longer being reset to the initial parameters when the page was changed. I imagine doing it the other way (swapping ChildComponent to use withApollo) could have worked as well, but hard to say without knowing the root of the problem.

Hope this helps someone out there.

This error is still present in "react-apollo": "3.1.3"

graphql(getLocations, {
  props: ({ data: { users, refetch, updateQuery, loading, error } }) => {
    // ERROR HUNT: The problem is that the previously used query variables
    //             are not removed when passing new variables
    //             this can be observed in the apollo console
    return {
      title: 'Locations',
      locations,
      refetch,
      updateQuery,
      loading,
      error
    }
}

and in component:

handleSubmit = () => {
    const {
      form: { getFieldsValue },
      updateQuery,
      refetch
    } = this.props

    let fields = getFieldsValue()
    fields = omit(fields, value => value == null || value === '')

    // this is not working, variables used in previous query are not updated/removed
    //refetch({ ...fields, dummy: Math.random() })
    refetch({ ...fields })
  }

Example:

Run query with let fields = { id: "5e36e69924aa9a0007624981", name_contains: "Bob" }

Apollo "watch query" console output:

Variables:

id="5e36e69924aa9a0007624981",
name_contains="Bob"

Then run query with let fields = { name_contains: "Marie" }

Apollo "watch query" console output:

Variables:

id="5e36e69924aa9a0007624981",
name_contains="Marie"

Temporary workaround:

  • always send ALL variables with each query
  • set the ones we don't use to undefined
export function fixSearch(_fields: Object) {
  return mapObject(_fields, val =>
    val == null || val === '' ? undefined : val
  )
}
refetch(fixSearch(fields))

I managed to get it working with the fetchPolicy change and also sending all the variables.

const { loading, data, error, fetchMore } = useQuery(
    QUERY_TRANSFERS, {
    variables: { 
      filter1: myfilter,
      cursor: null,
    },
    fetchPolicy: "network-only"
  });

and later on, load more:

fetchMore({
  variables: {
    filter1: dateFilter,
    cursor: endCursor,
  },
  updateQuery: myUpdateQueryFunction
})

I have this problem as well. Refetching a query with the same variables (that delivers a different result bc it's random) does return new data visibly in the network debugger, but the cache is not being updated. adding fetchPolicy: 'network-only' does not help. @apollo/client 3.0 beta-43

Still experiencing this issue with refetch in "react-apollo": "3.1.4". My workaround was to simply:

import { useApolloClient } from '@apollo/react-hooks';

client.query({ query: SEARCH_DISCOUNTS, variables })
   .then(response => {
      // do other stuff with the response
   });

Please reopen the issue. @apollo/[email protected]

In my pagination test the cache is updated after refetch only the first time. Consequent fetches, as @mschipperheyn said, just ignore new data. Clearly something's broken there.

  • Sending ALL variables.
  • fetchPolicy has no effect on this.

Workarounded by injecting random: Math.random() field into the query.
Getting more bizarre.

Update: looks like the same workaround hack was used by others
https://github.com/apollographql/react-apollo/issues/3315
🤣

Was this page helpful?
0 / 5 - 0 ratings