How to "watchQuery" from mapQueryToProps?


#1

How can I “watch” a query from the connect()'s mapQueriesToProps?

I cannot find an example of this anywhere.


#2

mapQueriesToProps always uses watchQuery under the hood. What specifically are you trying to do?


#3

it doesn’t seem to be reactive. I assume I have to return a cursor?


#4

Currently Apollo Client is not reactive, but you can turn on refetching via pollingInterval: http://docs.apollostack.com/apollo-client/core.html#watchQuery

You can also call refetch on the query handle if you want to manually reload the data.

Reactivity is something we want to add later after we get the non-reactive fetching right.


#5

Actually, contrary to the example, adding “pollInterval” does not re-trigger the query (also tried pollingInterval but the doc states that its “pollInterval”).

How do you plan to bring Reactivity to the Apollo Client? Will it be done using cursors much like the current Meteor DDP? Or will it be done using an interval?


#6

Correction. pollInterval worked, but only under watchQuery(). Inside “mapQueriesToProps”, the intervals did not trigger.


#7

Correction again. It worked with “returnPartialData: true”.

Why is this the case? Why can’t I poll with partial data false?


#8

Correction again… It only worked because I had a separate watchQuery() inside the componentWillMount…

mapQueriesToProps doesn’t seem capable of watching a query. Is there an example of watchQuery used inside mapQueriesToProps?


#9

I think it could just be a bug if pollInterval doesn’t work inside connect.

Can you post a code sample? I’m pretty sure @jbaxleyiii is using it, so maybe it’s some edge case.


#10
function mapQueriesToProps({ownProps, state}) {
  return {
    gql: {
      query: gql`
        query doTest( $choices: [String]) {
          test( getChoices: $choices) {
            _id
            someValue
          }
        }`,
      variables: {
        choices: ["abc","def","ghi"],
      },
      forceFetch: false,
      returnPartialData: true,
      pollInterval: 250,
    },
  }
};

export default connect({
  mapQueriesToProps,
})( (props,context) => {
  if (props.gql.loading)
    return <Loading />
  return <SomeComponent {... props} />
});

What is funny however is that if I keep this exact same code and add the exact same query inside componentWillMount() as a watchQuery() … subscribe (as shown in example in docs), then the mapQueriesToProps intervals start to work.

That was a surprise to me because the subscription was basically making the mapQueriesToProps re-fetch.


#11

Yeah, it’s because there is one global store, so updating that data also updates the data in the component. Working on a diagram to explain this. Let me see if I can come up with a test case and verify that it doesn’t work.

Thank you for trying this out and reporting!


#12

I’ll take a look and write a test in react-apollo to verify the intended funcationality! Sorry its not working correctly!


#13

also, why is “returnPartialData: true” necessary?

Why can’t the pollInterval work with returnPartialData set to false?


#14

The intention of returnPartialData is so that you can decide if you want to get partial data from what happened to be in the store at the time. Polling should work with and without it, the difference being that while loading is true you will only get results if returnPartialData is true. Perhaps we should get rid of returnPartialData entirely, because the loading state is probably enough information.


#15

Well then this definitely looks like a bug.

If returnPartialData is false, the pollingInterval doesn’t happen at all, period. When returnPartialData is false, none of the subscription code take place, no error no result, just silence.


#16

I’m glad we found the bug!


#17

@ashah888 @sashko

Yep it was a bug! Fixed and added a test with https://github.com/apollostack/react-apollo/pull/44


#18

Now there’s a different problem after upgrading to the latest apollo-client.

When you set “returnPartialData: true” and “pollInterval: ###” inside the mapQueriesToProps function, the query will fail with a warning message something like “Can’t find field … on object”.

Only way to solve this is by setting returnPartialData to false, but then the pollInterval doesn’t work so the query is not “reactive”.


#19

@ashah888 what version of apollo-client are you using?


#20

Yeah we are fixing bugs every day, so it’s good to check that you are always using the latest version.