Variable is used before being assigned using Next JS and Server Actions

112 views Asked by At

I'm working with a Next JS new Data Fetching feature to load data from an API and assigns it to a variable called 'contact.' However, I'm encountering the error message "variable 'contact' is used before being assigned."

I want to ensure that I handle this situation correctly and prevent the error from occurring. How can I properly structure my server action to load data from the API and assign it to 'contact' so that the error is resolved, and I can work with the data as expected?

export default async function Page() {
    let contact: Contact

    try {
        [contact] = await getContact(104);
    } catch (e: FetchError) {
        console.log(e.message)
    }

    ......
    <EditContactForm contact={contact}/>  <-- Variable is used before being assigned

Edit What works is if I retrieve the data as follows:

const [contact] = await getContact(104).catch((err) => {
    console.log(err.message)
}) || []

But I prefer to use try-catch statement, so how can I convert it?

2

There are 2 answers

3
Helper On

The TS is thinking that it isn't necessary for the contact to have a value when it is being used.

Just add a guard:

{
     contact && <EditContactForm contact={contact}/>
}

This will make sure that the EditContactForm is rendered only when the contact is defined.

1
Enjoy Coding. On

This is because the 'contact' variable is being used before it's assigned a value.

To fix this issue, you can initialize the 'contact' variable with a default value or handle the case where the API call fails and 'contact' remains undefined.

export default function Page({ initialContact }: { initialContact?: Contact }) {
  const [contact, setContact] = useState<Contact | undefined>(initialContact);

  useEffect(() => {
    async function fetchData() {
      try {
        const [fetchedContact] = await getContact(104);
        setContact(fetchedContact);
      } catch (error) {
        console.log(error.message);
      }
    }

    if (!initialContact) {
      fetchData();
    }
  }, [initialContact]);

  // Render loading state while contact is being fetched
  if (!contact) {
    return <div>Loading...</div>;
  }

  return <EditContactForm contact={contact} />;
}