Apollo-client: Refetch query with new variables at runtime

Created on 20 Apr 2016  路  15Comments  路  Source: apollographql/apollo-client

Hey @stubailo @jbaxleyiii

Relay provides an option in the component called setvariables to change the variables on runtime. Does apollo client support this yet? I see refetch function, but it works like refresh button, which wouldn't be helpful if someone wants to change the variables and then refetch the query. I think this option could be super useful for things like infinite scroll pagination or filtering - one can set the variable on runtime and fetch the updated data to update the store with new data.

Most helpful comment

Hi @stubailo I did the same thing for passing variables for this demo app: https://github.com/gauravtiwari/apollo_on_rails/blob/master/app/assets/javascripts/components/posts/show.es6.js#L41, but I think to utilise refetch() with new variables would be much more clear and easy to use.

For example: In infinite scroll pagination, we could just change the number of new records to fetch and page offset and it would fetch the new data.

variables: {
  first: 20,
}

Later for refetching:

this.refetch({
  variables: {first: 40, page: 2}
});

All 15 comments

If you want to pass new variables you can just unsubscribe from the previous query and start a new one.

react-apollo makes this really convenient: You can easily pass in a prop from outside, or put your state in Redux. The mapQueriesToProps option takes in ownProps and state, which can be used as variables in your query.

See this example (this is using data from Meteor.userId() but you could put other stuff in there):

https://github.com/apollostack/meteor-starter-kit/blob/3950b23ee39be144168a3f4d9f56ebeafb912533/imports/ui/App.js#L21-L44

However since we already have the refetch helper method, it would be pretty simple to have that take in a new set of variables.

Hi @stubailo I did the same thing for passing variables for this demo app: https://github.com/gauravtiwari/apollo_on_rails/blob/master/app/assets/javascripts/components/posts/show.es6.js#L41, but I think to utilise refetch() with new variables would be much more clear and easy to use.

For example: In infinite scroll pagination, we could just change the number of new records to fetch and page offset and it would fetch the new data.

variables: {
  first: 20,
}

Later for refetching:

this.refetch({
  variables: {first: 40, page: 2}
});

@johnthepink would your pagination for the app do something similar if present?

Based on how refetch works right now I think it would be trivial to build!

@stubailo thoughts on passing just an object of variables vs passing a QueryOptions object?

Hmm lets keep variables only for now until someone has a need for the other stuff?

@jbaxleyiii I think for a component, the query mostly revolves around variables (if any), so mutating just the variable object and then have some kinda of observer to detect that the variable changed and refetch (I guess that's how refetch works right now, but with variables)

@jbaxleyiii it totally could. I'm just updating redux and letting it unsubscribe and start over (mixed with shouldComponentUpdate). I think I like the refetch idea better though, because the unsubscribe currently removes the data from the store and then adds it back. Which, if you are trying to render components based off the store is a little wonky.

Cool, I'll see about knocking this out now

Added with #133

Published as 0.1.5!

Why do I have to manually call refetch on options.variables change? From stepping through the code, the query keeps a hold of this.options, instead of using new options (which it does get, it just ignores them)

My use case is that my component receives a string from a redux store. If this string has a length of 4, I want to ask the server for its value. So I have

{
    skip: ({ postal_code: code }) => !code || code.length !== 4,
    options: ({ postal_code: code }) => ({ variables: { code } }),
}

What happens is that the first time code.length === 4, a request goes to the server. But all other times, the result of that one query will be returned, with no new request sent to the server, unless I manually unmount the component (which I don't want to).

EDIT: changing to skip: ({ postal_code: code }) => !code, makes the problem go away. I mean, I get wasted calls to the backend, but at least new options are set correctly. I stopped getting unsubscribed here: https://github.com/apollostack/react-apollo/blob/2e305d9c3211f1ba3dd31675b3acb1d34dc0558b/src/graphql.tsx#L283-L289 and suddenly it works. Is it a bug, or am I misunderstanding something?

@SimenB this is a _really_ old issue and the entire codebase has been rewritten since April. Can you open a new issue please?

Was this page helpful?
0 / 5 - 0 ratings