skip to Main Content

I am experiencing a problem that when I call the "map" function to iterate over a array of objects that was created using useState, I get a error saying that "map" is not a function.

It works fine if I use it on a manuually defined array like `const array = [a, b, c] but when using useState, it does not.

I created the array like this (Notice that I only pasted the parts that are actually doing this.)

// Etc

async function getFicharpgs(login_usuario) {
    // Step 1 - Get my JSON Data from my API.
    try {
        const response = await axios({
            method: "post", url: "http://localhost:3000/usuario_ficharpg/listar_fichas", data: {"login": login_usuario}
        });

        // Console Log prints perfectly (Printed image below.)
        console.log('getFicharpgs => Resposta completa:', response);
        console.log('getFicharpgs => Lista de Fichas do Usuário Recebida:', response.data);

        return response; // This returns my response data, including my JSON Data.

// Etc

function Ficharpg({objeto_props}) {
    const {login_usuario} = objeto_props;

    // Step 2 - Create my array list as a state variable to be passed on to another component
    const [ficharpgs, setFicharpgs] = useState([]);

// Etc

useEffect(() => {
        // Step 3 - Pass the data I got from my getter to my useState array.
        if (login_usuario) {
            // Espera a função assíncrona getUsers ser concluída antes de finalizar o efeito (Renderizar o Componente).
            getFicharpgs(login_usuario)
                // Implantacoes de Then/Catch para resolver "Promise Ignorada" e fazer regras de negocio.
                .then(response => {
                    // Entra aqui caso o nosso status tenha sido 200 - [Object object]
                    console.log(`Componente Ficharpg => Fichas de RPG do Usuario Recebidas com sucesso. Status: ${response.status}`);

                    // Mudo o estado para dizer que o carregamento dos dados terminou
                    setdadosCarregando(false);

                    // Here is where I add my data from my response into the state variable.
                    setFicharpgs(response.data);  // Step 3 Completed here.

// Etc

    // Render the data from my useState array.
    return (<div>
        {/* If Ternario que checa se os dados estao sendo carregados. */}
        {dadosCarregando ? (<p>Selecione qual usuário vai mostrar as fichas.</p>) : (<table>
            <thead>
            <tr>
                <th>Fichas de RPG do Usuario {login_usuario}</th>
            </tr>
            <tr>
                <th>Nome</th>
                <th>Classe</th>
                <th>Raca</th>
                <th>Nivel</th>
                <th>Alinhamento</th>
            </tr>
            </thead>
            <tbody>

            {/* Step 4 - Iterate over my list and print my objects. */}
            {ficharpgs.map((ficharpg, ficharpg_id) => (
                // Index Key: ID da Ficha do RPG, identificador da nossa "linha" (Table Row) - Key => Built-In Do JavaScript.
                <tr key={ficharpg_id}>
                    <td>name: {ficharpg.nome}</td>{" "}
                    <td>age: {ficharpg.classe}</td>
                    <td>age: {ficharpg.raca}</td>
                    <td>age: {ficharpg.nivel}</td>
                    <td>age: {ficharpg.alinhamento}</td>
                </tr>
            ))}

// Etc

So, at step 4, I was expecting it to print my data from the array, but instead, I am getting the following error:

ficharpgs.map is not a function
TypeError: ficharpgs.map is not a function

I already tried to look into another posts from users that had the same problems, like this one:

ReactJs useState .map() is not a function

But I was not able to fix it reading the answer from it. 🙁

Edit

Just a quick edit, here is the output of a console.log from inside my getter function that prints the response itself:

Console Log from the Getter

And this is the output of a console.log from inside my component, that prints my useState array:

Console.log of my useState array

2

Answers


  1. This is a common error that happens when the variable you referred to is not an array.

    map() is a method of an array, so if the variable is not an array, it will throw this error.

    As your screenshot says, the response of getFicharpgs() API call is an object, not an array.

    So, you need to get the correct array:

    getFicharpgs(login_usuario)
      .then(response => {
        // ...
        setFicharpgs(response.data.ficas_do_usuario);
    
    Login or Signup to reply.
  2. The issue is timing.

    When the component loads its is performing an async axios request for data, while this is happening the component continues to load which means it is encountering the map iterator before the axios call has returned and the ficharpgs state has actually been set. You are effectively trying to call map() on undefined.

    The solution is to check the state before trying to iterate:

    {ficharpgs && ficharpgs.map((ficharpg, ficharpg_id) => (
    

    This ensures when the component first loads and the ficharpgs state is the default value (in this case undefined) map is ignored. When the axios call returns and the ficharpgs state is updated, the update causes the component to refresh and provided that ficharpgs now has a value, map is actioned.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search