0

In my app I have a sidebar with a list of "saved searches" and a central area that should show the results of a search. Whenever I click on a saved search link, I want to update the central area with the results of that search.

What is the proper way to do this with apollo-react?

I tried with this:

// SidebarConnector.js:
const withVideoSearch = graphql(
  VIDEO_SEARCH_QUERY,
  {
    name: 'videoSearchQuery',
    props: ({ videoSearchQuery }) => {
      return ({
        searchVideos: videoSearchQuery.refetch,
      });
    },
  }
);
export default withVideoSearch(Sidebar);

My saved searches are doing a searchVideos({ query: "some query" }) on click which, based on the above, is doing a refetch for the VIDEO_SEARCH_QUERY query with different variables. This works fine, the call is made to the graphql server and results are returned just fine.

For the main component that shows the list of results I use:

export default graphql(VIDEO_SEARCH_QUERY)(ResultList);

Initially the main component gets its results from the server as if the query was done without variables which is fine, exactly how I want it.

The problem is that every refetch seems to create a different entry in ROOT_QUERY in apollo's store and my main component is "locked" into the one without variables.

Here's what apollo's store looks like after the initial fetch and one of the refetches triggered from a saved search:

ROOT_QUERY
  searchVideos({"query":"coke"}): [Video]
    0:▾Video:arLaecAu5ns
  searchVideos({"query":null}): [Video]
    0:▾Video:3HXg-oVMA0c

So my question is how to either switch the main component to the "current search" or how to overwrite the store on every refresh so that there's only one key so the main component updates correctly.

For completeness here's my VIDEO_SEARCH_QUERY:

export const VIDEO_SEARCH_QUERY = gql`
  query searchVideos($query: String) {
    searchVideos(query: $query) {
      ...fVideo
    }
  }
  ${fVideo}
`;
Dan Caragea
  • 1,784
  • 1
  • 19
  • 24

1 Answers1

1

Maybe I'm misunderstanding your use case, but it seems like there's no need to utilize refetch here. It would be simpler to persist whatever the selected search string is as state, pass that state down as a prop to your main component and then just use that prop as the variable in your GraphQL request. So the graphql call inside your ResultList component would look something like this:

const options = props => ({ variables: { query: props.searchString } })
export default graphql(VIDEO_SEARCH_QUERY, { options })(ResultList);

Then just have your onClick handler for each saved search set the state to whatever that search string is, and Apollo will do the rest. This is super easy with Redux -- just fire off the appropriate action. If you're not using Redux, you may have to lift the state up so it can then be passed down as a prop, but the concept is the same.

Daniel Rearden
  • 80,636
  • 11
  • 185
  • 183