React-apollo: TypeError: Cannot read property 'queries' of undefined

Created on 20 Sep 2016  路  7Comments  路  Source: apollographql/react-apollo

I just updated to [email protected] and [email protected] and my application is now crashing with the error:

 TypeError: Cannot read property 'queries' of undefined

The error refers to this line.

I do SSR and I integrate with redux. I use apollo as name of the key for the apollo state.
Despite the initial state is passed correctly from the server to the frontend app the frontend fails to find the the name of key in which apollo state is stated.

The line I linked gets the reduxRootKey from the client. However client.reduxRootKey is undefined.

My app works if I explicitly set the reduxRootKey when I create the client:

new ApolloClient({
    ...
    reduxRootKey: 'apollo'
});

I know that reduxRootKey has been deprecated in [email protected], so this may be its bug.

However, the function should be updated to use reduxRootSelector instead.

I can make a PR if needed.

Most helpful comment

Great. I will try to make a PR asap. My first contribution to react-apollo so it may take a moment to get into the code.

All 7 comments

@rewop that's exactly the issue! If you can produce a PR to support both Key and Selector and add a deprecation warning in react-apollo if Key is the one used, that would be awesome! In the meantime, the client should also be patched (see https://github.com/apollostack/apollo-client/issues/676)

Yep, the newest release has reverted this change, and we're going to work on making it more backwards compatible before shipping it again.

Great. I will try to make a PR asap. My first contribution to react-apollo so it may take a moment to get into the code.

@rewop great to have new contributors! Hopefully it will not be that hard. The codebase is quite easy to get started with :wink:

@rricard I gave it a look, and this would be my approach:

I would create a function called getReduxRootKey(client : ApolloClient, store: ApolloStore) : string which would be implemented something like follows:

function getReduxRootKey(client, store) {
  // warn if client is using deprecated apollo client reduxRootKey prop
  if (client.reduxRootKey) {
    console.warn(`
      Property 'reduxRootKey' from apollo client deprecated and its usage
      will be removed from the next releases.
      Use 'reduxRootSelector' instead when creating the apollo client.
    `)
  }

  if (this.client.reduxRootKey) {
    return client.reduxRootKey;
  }
  else if (typeof this.client.reduxRootKey === 'string') {
    return client.reduxRootSelector;
  }
  else if (typeof this.client.reduxRootKey === 'function') {
    return reduxRootSelector(store.getState());
  }
  // fallback to default value
  return 'apollo';
}

I also noticed that the reduxRootKey is used in the server.ts file. For that reason, I am thinking to place the function in a separate file (please help here with naming convention).

Finally, I suggest to store the root key in a new prop of the class Graphql.

If you guys think this is a good approach, I will proceed with the implementation.

_noob alert_
Since I am not familiar with typescript, I may need some help to make sure my code will work :). Do you have any link I can look for an overview of the setup?

I think I overlooked the implementation of the reduxRootSelector, because it could returns ApolloStore type and not String. So may previous example is wrong.

So the function actually can just return the apollo state:

import ApolloClient, {
  ApolloStore
} from 'apollo-client';

// makes sure to retrieve the key in the redux state
// see https://github.com/apollostack/apollo-client/issues/676
export function reduxRootSelector(client: ApolloClient) : ApolloStore {
  const state = client.store.getState()
  if (client.reduxRootKey) {
    return state[client.reduxRootKey];
  }
  else if (typeof client.reduxRootKey === 'string') {
    return state[client.reduxRootSelector];
  }
  else if (typeof client.reduxRootKey === 'function') {
    return client.reduxRootSelector(state);
  }
  // fallback to default value
  return state.apollo;
}

Fixed in 0.5.7

Was this page helpful?
0 / 5 - 0 ratings