Home > Net >  React array state is being returned as object
React array state is being returned as object

Time:11-12

I am using a MUI Autocomplete field that takes an array for options. I created this hook that takes the input value and fetches the API based on it. This is the code for it:

import axios from "axios";
import { useEffect, useState } from "react";
export default function useFetchGames(searchString) {
  const [gameSearch, setGameSearch] = useState([]);

  useEffect(() => {
    if (searchString) setGameSearch(fetchData(searchString));
  }, [searchString]);

  return gameSearch;
}

const generateSearchOptions = (array) => {
  const tempArray = [];
  array.map((item) => {
    tempArray.push(item.name);
  });
  return tempArray;
};

async function fetchData(searchString) {
  const res = await axios
    .post("/api/games", { input: searchString })
    .catch((err) => {
      console.log(err);
    });

  return generateSearchOptions(res.data);
}

And then i am calling this hook in the component where i have the autocomplete element.

const searchOptions = useFetchGames(inputValue);

The issue is,useFetchGames is supposed to return an array since the state is an array. But whenever the input changes, i get an error that you cant filter or map an object. Basically Autocompolete element is trying to map searchOptions but it is not an array. I even tried to log its type with log(typeof searchOptions); and it returns an object. I dont understand what I am doing wrong.

Edit: Here is the log of res.data. it is an array of objects. That is why i am remapping it to an array of just the names. enter image description here

CodePudding user response:

you get the promise back when you invoked fetchData(searchString) as it is an async function which always return a promise back

I would do it as

useEffect(() => {
  // wrapping it as a async function so we can await the data (promise) returned from another async function
  async function getData() {
    const data = await fetchData(searchString);
    setGameSearch(data);
  }
  if (searchString) {
    getData();
  }
}, [searchString]);

also refactoring this generateSearchOptions function in order to remove the creation of temp array which I feel is not required when using a map - below as

const generateSearchOptions = (array) => array.map(item => item.name)

CodePudding user response:

when you are mapping over an array of objects, on each object you can use

Object.entries((obj)=> {
//whatever you wanna do

})

Object.entries(obj) will transform your object into an array.

  • Related