Filtering: Searching the List of Links

In this section, you’ll implement a search feature and learn about the filtering capabilities of your GraphQL API.

Preparing the React components

The search will be available under a new route and implemented in a new React component.

Again, this is a pretty standard setup. You’re rendering an input field where the user can type a search string.

Notice that the links field in the component state will hold all the links to be rendered, so this time we’re not accessing query results through the component props! We’ll also talk about the withApollo function that you’re using when exporting the component in a bit!

For the user to be able to comfortably navigate to the search functionality, you should also add a new navigation item to the Header.

You can now navigate to the search feature using the new button in the Header:

Great, let’s now go back to the Search component and see how we can implement the actual search.

Filtering Links

This query looks similar to the feed query that’s used in LinkList. However, this time it takes in an argument called filter that will be used to constrain the list of links you want to retrieve.

The actual filter is built and used in the feed resolver which is implemented in server/src/resolvers/Query.js:

.../hackernews-react-apollo/server/src/resolvers/Query.js
async function feed(parent, args, ctx, info) {
  const { filter, first, skip } = args // destructure input arguments
  const where = filter
    ? { OR: [{ url_contains: filter }, { description_contains: filter }] }
    : {}

  const queriedLinks = await ctx.db.query.links({ first, skip, where })

  return {
    linkIds: queriedLinks.map(link => link.id),
    count
  }
}

Note: To understand what’s going on in this resolver, check out the Node tutorial.

In this case, two where conditions are specified: A link is only returned if either its url contains the provided filter or its description contains the provided filter. Both conditions are combined using Prisma’s OR operator.

Perfect, the query is defined! But this time we actually want to load the data every time the user hits the search-button - not upon the initial load of the component.

That’s the purpose of the withApollo function. This function injects the ApolloClient instance that you created in index.js into the Search component as a new prop called client.

This client has a method called query which you can use to send a query manually instead of using the graphql higher-order component.

The implementation is almost trivial. You’re executing the FEED_SEARCH_QUERY manually and retrieving the links from the response that’s returned by the server. Then these links are put into the component’s state so that they can be rendered.

Go ahead and test the app by running yarn start in a terminal and navigating to http://localhost:3000/search. Then type a search string into the text field, click the search-button and verify the links that are returned fit the filter conditions.

Unlock the next chapter
What's the purpose of the 'withApollo' function?
You use it to send queries and mutations to a GraphQL server
When wrapped around a component, it injects the 'ApolloClient' instance into the component's props
You have to use it everywhere where you want to use Apollo functionality
It parses GraphQL code