Search code examples
reactjsgraphqlreact-hooksapolloapollo-client

Apollo GraphQL query inside of react custom hook


I'm trying to list all the characters from Rick & Morty API. I wrote the following hook to use in my Component that is going to render the result. When I hardcoded values eg: (page: 1 , filter: { name : "Rick"}) The query runs just fine.If I try to use variables it returns an error 400 bad request (I'm assuming this means my $page / $filter values are invalid and I tried to check the values within them + their types everything seemed fine)I looked at the documentation at Apollo | Queries - Client (React) and made sure that I was using the proper syntax to inject variables into the query. The query is from the official Rick & Morty API docs API Docs. Any guidance/direction is much appreciated.

useCharecterList Hook Params: page: Number | filter: String

import { useQuery, gql } from '@apollo/client';

const CHARECTERS_LIST = gql`
query ($page: Number!, $filter: String!){
  characters
    (page: $page , filter: { name : $filter}) {
        info {
          next
          prev
        }
        results {
          id
          name
          image
        }
      }
  }
`;

export default function useCharecterList({page, filter}){  
    return useQuery(CHARECTERS_LIST, {
      variables: {page, filter}
    });
}

Component Rendering the results:

import useCharecterList from '../hooks/useCharecterList'
import { Fragment } from 'react';
import InputComponent from './InputComponent';


function CharectersList() {
  const { loading, error, data } = useCharecterList({page: 1, filter: "Rick"});
  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;
  const options = data.characters.results.map(({name}) =>{
      return name;
  })
  return(
    <Fragment>
      <InputComponent options={options}></InputComponent>
      {
           data.characters.results.map(({ id, name, image }) => (
            <div key={id}>
                <img src={image} alt={`${name} from the popular sitcom Rick & Morty`}/>
                <p>{name}</p>
            </div>
          ))
      }
    </Fragment>
  )


}

export default CharectersList


Solution

  • I figured it out... Like an Idiot I assumed the query types are just your normal JS types. After some digging I got it to work as follows.

    import { useQuery, gql } from '@apollo/client';
    
    const CHARECTERS_LIST = gql`
    query CharectersList($page: Int!, $filter: FilterCharacter!){
      characters
        (page: $page, filter: $filter) {
            info {
              next
              prev
            }
            results {
              id
              name
              image
            }
          }
      }
    `;
    
    export default function useCharecterList(options){  
        return useQuery(CHARECTERS_LIST, options);
    }

    import useCharecterList from '../hooks/useCharecterList'
    import { Fragment } from 'react';
    import InputComponent from './InputComponent';
    
    
    function CharectersList() {
      const { loading, error, data } = useCharecterList({variables: {page: 1, filter: { name: "Summer" }}});
      if (loading) return <p>Loading...</p>;
      if (error) {
        console.log(error);
        return <p>Error :(</p>}
      const options = data.characters.results.map(({name}) =>{
          return name;
      })
      return(
        <Fragment>
          <InputComponent options={options}></InputComponent>
          {
               data.characters.results.map(({ id, name, image }) => (
                <div key={id}>
                    <img src={image} alt={`${name} from the popular sitcom Rick & Morty`}/>
                    <p>{name}</p>
                </div>
              ))
          }
        </Fragment>
      )
    
    
    }
    
    export default CharectersList