Jevon Cochran
Jevon Cochran

Reputation: 1774

How to account for array "is possibly undefined" error in Typescript

I have an array called availableOfferings that gets set after an API call is completed.

const { offerings: availableOfferings } = useGetOfferings();

Then, I have two variables that rely on the data contained in availableOfferings

const bestOffering = availableOfferings[0];

const relevantOfferings = availableOfferings
    .slice(1)
    .filter((off: any) => isGoodFit(off));

When initialized the two variables above, I get a Typescript error that says 'availableOfferings' is possibly 'undefined'.

What is the best way to resolve this issue?

I tried this and it worked but doesn't look too elegant:

const bestOffering = availableOfferings ? availableOfferings[0] : undefined;

const relevantOfferings = availableOfferings
  ? availableOfferings.slice(1).filter((off: any) => isGoodFit(off))
  : undefined;

Here is how the data is being pulled with useGetOfferings:

export const OfferingsContext = createContext<{
  [x: string]: any;
  offerings?: {
    [x: string]: any;
  };
}>({
  offerings: {},
});

export function useGetOfferings() {
  return useContext(OfferingsContext);
}
function OfferingsProvider({ children }: Props) {
  const [offerings, setOfferings] = useState([]);
  const [hasGoodFits, setHasGoodFits] = useState(undefined);
  const { getAccessTokenSilently } = useAuth0();
  const fetchData = async () => {
    try {
      const responseOfferings = await BusinessApi.getOfferings(
        getAccessTokenSilently
      );
      const hasGoodFitsResult = responseOfferings.data.data.some(
        (offering: any) => isGoodFit(offering)
      );
      setOfferings(responseOfferings.data.data);
      setHasGoodFits(hasGoodFitsResult);
      return { responseOfferings, hasGoodFitsResult };
    } catch (error) {
      console.log(error);
    }
  };
  useEffect(() => {
    fetchData();
  }, []);


  return (
    <OfferingsContext.Provider
      value={{ offerings, fetchData, hasGoodFits }}
      children={children}
    />
  );
}

Upvotes: 0

Views: 70

Answers (2)

haptn
haptn

Reputation: 987

You can give the availableOfferings a default value as [], so it always has a fallback value => the warning will be gone.

const { offerings: availableOfferings = [] } = useGetOfferings()

But I'm not sure why you declare your offerings with type object instead of type array (in OfferingsContext).

Upvotes: 1

Terry
Terry

Reputation: 66133

That's when optional chaining ?. and nullish coalescing operator ?? comes into handy:

const bestOffering = availableOfferings?.[0];

const relevantOfferings = (availableOfferings ?? [])
    .slice(1)
    .filter((off: any) => isGoodFit(off));

Upvotes: 2

Related Questions