0

Solution: "data" from the Apollo query was not arriving on time for a check in the options property of the Autocomplete component, even though loading was complete. My final code for the Autocomplete component:

<Autocomplete
                    multiple
                    disabled={loadingConcepts}
                    value={narrowerConceptsV || null}
                    onChange={(event, newNarrowerConcepts) => {
                      setNarrowerConcepts(newNarrowerConcepts);
                    }}
the solution >>>>   options={!loadingConcepts && data ? data.concepts : []}
                    getOptionLabel={(option) => option.name}
                    renderInput={(params) => (
                      <MDInput {...params} variant="outlined" label="Narrower Concepts" />
                    )}
                  />

Original Post:

I am trying to pull a list of concept names from my neo4j auraDb. I had it working at one point but one I started working on my refetching, something went wrong and now I get an error no matter what I do. The error is occurring in the react component below.

The error messages:

<index.js:165 Uncaught TypeError: Cannot read properties of undefined (reading 'concepts')>
<react_devtools_backend.js:4026 The above error occurred in the AddConcept component:>
<index.js:165 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'concepts')>

The code in question (all in the same file).

The gql and apollo hook:

    import { gql, useMutation, useQuery } from "@apollo/client";
    
    const GET_CONCEPTS = gql`
        query GetConcepts {
          concepts {
            uid
            name
          }
        }
      `;

const { loadingConcepts, errorConcepts, data, refetch } = useQuery(GET_CONCEPTS, {
    fetchPolicy: "network-only",
  });

The react component. The error is being caused here by "data.concepts". :

                 <Autocomplete
                    multiple
                    disabled={loadingConcepts}
                    value={broaderConceptsV || null}
                    onChange={(event, newBroaderConcepts) => {
                      setBroaderConcepts(newBroaderConcepts);
                    }}
                    options={loadingConcepts ? [] : data.concepts}
                    getOptionLabel={(option) => option.name}
                    renderInput={(params) => (
                      <MDInput {...params} variant="outlined" label="Broader Concepts" />
                    )}
                 />

This autocomplete component is within an MUI form with a submit function. The console.log here accurately outputs the array if I put in any valid object for data.concepts above. The code for the submit function:

const handleSubmit = async (e) => {
e.preventDefault();
createConcepts({
  variables: {
    uid: uuidv4(),
    name: nameRef.current.value,
    block: blockV,
    addedBy: user.uid,
  },
});
console.log(data.concepts);
refetch(data); };
rvhorton
  • 13
  • 4
  • Try adding the Optional chaining mark: `data?.concepts` – Alon Barenboim Oct 07 '22 at 19:19
  • That did something. Changed the error to: Uncaught TypeError: Cannot read properties of undefined (reading 'length') – rvhorton Oct 07 '22 at 19:22
  • Do the same before `length`, wherever it is inside your component :) – Alon Barenboim Oct 07 '22 at 19:23
  • You can read more about this here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining – Alon Barenboim Oct 07 '22 at 19:24
  • Okay. I presume that the .length error is getting thrown because of the mapping of getOptionLabel just below the "data.concepts" line. But I think my confusion is more about why data.concepts is undefined when loadingConcepts is false (data.concepts should already be loaded)? – rvhorton Oct 07 '22 at 19:36
  • `const { loadingConcepts, errorConcepts, data, refetch } = useQuery(…)` should be `const { loading, error, data, refetch } = useQuery(…)` – Michel Floyd Oct 07 '22 at 22:46
  • I have a mutation in this file as well so I changed loading and error for the query to avoid duplicate variable names. – rvhorton Oct 09 '22 at 20:45

1 Answers1

1

Maybe your data is not there yet.... try to wrap your component on a ternary operator like: { data ? <Autocomplete .../> : <p>Test></p>}

Maybe your data is there, but concepts not... so try to use the ternary operator when you try to access data.something

itsjagnezi
  • 26
  • 2
  • 1
    Thank you! Wrapping it in a ternary operator worked. I am going to keep playing with it to see if I can it to work without a full component wrap. If I get it I will post my ultimate solution in an edit. – rvhorton Oct 07 '22 at 19:52
  • 1
    Applying the same ternary logic directly to the options component worked. Thank you again. – rvhorton Oct 07 '22 at 19:54
  • I'm happy that works!!! Have a nice weekend bro – itsjagnezi Oct 07 '22 at 19:56
  • Oh. It has been a while since I helped you with that... but I didn't see your comments here jajaja... Have a lovely weekend too bro! – itsjagnezi Jun 09 '23 at 14:37