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.
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.