Home > Back-end >  Make conditional GraphQL request based on node type value in React component with Apollo Client
Make conditional GraphQL request based on node type value in React component with Apollo Client

Time:11-28

I am using React and Apollo Client.

Based on a node type value (nodes.type) from a GraphQL response, I want to conditionally make a GraphQL request to either below query NodeTypeOne or NodeTypeTwo.

// MyBlock.gql

export default gql`
  query NodeTypeOne {
    getNodesOne {
      nodes {
        id
        type
        title
      }
    }
  }
`;

export default gql`
  query NodeTypeTwo {
    getNodesTwo {
      nodes {
        id
        type
        title
      }
    }
  }
`;

So in below React component I want to conditionally make a GraphQL request based on the node type value.

import MyQuery from './MyBlock.gql';

const MyBlock = ({ data: myType }: Props) => {
  const { data } = useQuery<GqlRes>(MyQuery);

  const items =
    data?.items?.map((node) => {
      return {
        id: node.id,
        title: node.title,
      };
    }) || [];

  return data?.items?.length ? (
    <Slider items={items} />
  ) : null;
};

export default MyBlock;

How do I do this in a clean efficient way?

CodePudding user response:

There are several design patterns you can opt to solve problems. For your use case, the strategy design pattern will work smoothly. For code reference, you can google for a bunch of examples.

These are from my reference:-

https://dev.to/wecarrasco/strategy-pattern-with-javascript-dha

https://gist.github.com/Integralist/5736427

CodePudding user response:

As your query will target different resolvers, you cannot really create a single query from which you would target either the getNodesOne or getNodesTwo resolver.

useQuery on the other hand can take in parameter only a single, predefined query.

I would then go for 2 separate queries and use the apolloClient hook to conditionally call the right query:

// MyBlock.gql

export const QUERY1 = gql`
  query NodeTypeOne {
    getNodesOne {
      nodes {
        id
        type
        title
      }
    }
  }
`;

export const QUERY2 = gql`
  query NodeTypeTwo {
    getNodesTwo {
      nodes {
        id
        type
        title
      }
    }
  }
`;




import {QUERY1, QUERY2} from './MyBlock.gql';

const MyBlock = ({ data: myType }: Props) => {
const client = useApolloClient()
const [data, setData] = useState(null)

useEffect(() => {
  client.query({query: MyType === '?' ? QUERY1 : QUERY2})
  .then(({data}) => setData(data))
  .catch((err) => console.error(err))
}, [myType])

if(!data) return null /* or a loader... */

const items =
  data?.items?.map((node) => {
    return {
      id: node.id,
      title: node.title,
    };
  }) || [];

return data?.items?.length ? (
  <Slider items={items} />
  ) : null;
};

export default MyBlock;
  • Related