Home > Software engineering >  Setting GraphQL variable dynamically with React Hook is not working
Setting GraphQL variable dynamically with React Hook is not working

Time:12-23

I'm using the useEffect und useState react hook to set the GraphQL variable on select change event and populate the second select with the data depending on what option of the first dropdown was selected,

so when i choose Option A the gql variable should update like this:

{
  variables: {
     selectedOption: "A"
  }
}

but somehow the selectOption is not being set on useEffect(). Outside of useEffect the selectOption is effected by setSelectOption.

What am i doing wrong?

My GraphQL query:

import {gql} from "@apollo/client";

export const GET_SELECT = gql`
query getSelect($selectedOption: String!) {
  categories(where: {name: $selectedOption}) {
    edges {
      node {
        children {
          edges {
            node {
              name
            }
          }
        }
      }
    }
  }
}
`;

My React Component

import React, {useState, useEffect} from 'react';
import {useQuery} from "@apollo/client";
import {GET_SELECT} from "./app/queries/get-select";


const FilterBar = ({options}) => {
    const [ selectOption, setSelectOption] = useState('');
    const { data, loading, error } = useQuery(GET_SELECT, {
        variables: {
            selectedOption: selectOption
        }
    });


    useEffect(() => {
        setSelectOption(data?.categories?.edges?.map(first => first?.node?.children?.edges?.map(second => second?.node?.name)));
        console.log('select option'   selectOption);
    }, [data, setSelectOption]);


    if (loading) return "Loading...";
    if (error) return <pre>{( error?.message )}</pre>


    return (
        <>
            <select onChange={(e) => setSelectOption(e.target.value)}>
                <option value="">Select option</option>
                <option value="A">Option A</option>
                <option value="B">Option B</option>
                <option value="C">Option C</option>
            </select>
            <br/>
            <select>
                <option value="">Select data</option>
                {data &&
                    data?.map(opt =>
                        <option value={opt} key={opt}>{opt}</option>
                    )
                }
            </select>
        </>
    )
}


export default FilterBar;

CodePudding user response:

Please notice that setSelectOption don't update the value immediately. So, if you want to see the changes after that line, Try to add selectOption as a dependency or create new useEffect block which only include selectOption

useEffect(() => {
  setSelectOption(data?.categories?.edges?.map(first => first?.node?.children?.edges?.map(second => second?.node?.name)));
  console.log('select option'   selectOption);
}, [data, setSelectOption, selectOption]);

or

useEffect(() => {
  console.log('select option'   selectOption);
}, [selectOption])

For your Graphql query, try below code.

export const GET_SELECT = gql`
  query ($selectedOption: String!) {
    getSelect() {
      categories(where: { name: $selectedOption }) {
        edges {
          node {
            children {
              edges {
                node {
                  name
                }
              }
            }
          }
        }
      }
    }
  }
`;

CodePudding user response:

ok i figured out that the Graphql variable 'name' is returning an array so i had to change the query like so:

const GET_SELECT = gql` 
query getSelect($selectedOption: [String!]) {
  categories(where: {name: $selectedOption}) {
    edges {
      node {
        children {
          edges {
            node {
              name
            }
          }
        }
      }
    }
  }
}
`;

and in the react component:

const { data, loading, error } = useQuery(GET_SELECT, {
        variables: { name: [selectOption] },
    });

now everything is working properly

  • Related