Error, when sending props. Can not read properities of undefined (reading 'length')

Hello there. Im facing an issue in my project. Im trying to map an ARRAY but after doing this i got error in console. Cannot read properties of undefined (reading ‘length’) and after commenting this out I got: Cannot read properties of undefined (reading ‘map’)
After console.logging my array is undefined. So, it looks that theres is a problem in passing props from parent component. If anyone know where the problem is, I will apreciate if it will be pointed out. Tried to add ? in - {props.todos?.map((todo) but it doesnt help. shows only empty table, which i logical, because i got undefined props.

code snippets from file i get error and its aprent component:

import React from 'react';
import { TodoEntity } from 'types';
import { TodoTableRow } from './TodoTableRow';

interface Props {
  todos: TodoEntity[];
  onTodoChange: () => void;
}
export const TodosTable = (props: Props) => {
  console.log(props.todos);                      <- here I logg my props
  return (
    <table>
      <thead>
   {props.todos.length === 0 ? null : (                                 <-- here error occurs
          <tr>
            <th>Name</th>
            <th>Actions</th>
          </tr>
        )}
      </thead>
      <tbody>
        {props.todos.map((todo) => (                                    <-- here   error occurs
          <TodoTableRow
            todo={todo}
            key={todo.id}
            onTodoChange={props.onTodoChange}
          />
        ))}
      </tbody>
    </table>
  )};
and parent component down below:  

import React, { useState, useEffect } from 'react';
import { TodoEntity } from 'types';
import { Spinner } from '../../common/Spinner/Spinner';
import { TodosTable } from './TodosTable';
import { AddTodo } from './AddTodo';

export const TodosList = (userId: any) => { 
  const [todosList, setTodosList] = useState<TodoEntity[] | null>(null);

  const refreshTodos = async () => {
    setTodosList(null);
    const res = await fetch(`http://localhost:3001/todo/${userId}`);
    const data = await res.json();
    setTodosList(data.todosList);
  };
  useEffect(() => {
    refreshTodos();
  }, []);

  if (todosList === null) {
    return <Spinner />;
  }
  return (
    <>
      <div>
        <AddTodo onTodoChange={refreshTodos} userId={userId} />
      </div>
      <div>
        <h3>Todos:</h3>
        <TodosTable todos={todosList} onTodoChange={refreshTodos} />
      </div>
    </>
  );};
```    My backend is ok, everything work well, I will try to figure it out on my own, but I'm running out of ideas..

Can you post the output of your console here, too? We don’t see what type it is and if it has a length property.

this is my console output. No errors in frontend and backend terminals.

So here it is already undefined?
Can you then console.log todosList in your TodosList component and post the output of the console from your parent component?

this is console output in parent component.

  const [todosList, setTodosList] = useState<TodoEntity[] | null>(null);
  console.log(todosList);

Then apparently it’s not an issue of data getting lost when passed as props, but you’re either never receiving data or the data object doesn’t have a property todosList. What if you log data in refreshTodos?


this is the output

    setTodosList(null);
    const res = await fetch(`http://localhost:3001/todo/${userId}`);
    const data = await res.json();
    setTodosList(data.todosList);   
  };
  console.log(refreshTodos);

  useEffect(() => {
    refreshTodos();
  }, []);```

You’re logging the function itself → I meant logging the data within the function:

const refreshTodos = async () => {
    setTodosList(null);
    const res = await fetch(`http://localhost:3001/todo/${userId}`);
    const data = await res.json();
    console.log(data)
    setTodosList(data.todosList);
  };

Actually I can’t do it, because after adding login/register feature,
after user is logged in app crashes, with the output error i described earlier.
I wrote app from scratch, and without login feature it worked well, as it should. After user is logged in I should see the table with tasks and possibilities to add, remove, edit… But now instead of see the table whole application crashes. I know that backend is ok, tested all endpoints with postman. So, I dont understand why it is happening…

Then take this out of the parent component:

And this, too:

So you get rid of the error and you can see the output of the console.

You need to see the structure of the data you are getting.

After removing this , I dont see the table. I have another file which is important in this flow.

import { NavigationUser } from '../components/Navigation/NavigationUser';
import { useNavigate } from 'react-router-dom';
import { TodosList } from '../components/Todos/TodosList';
import { Spinner } from '../common/Spinner/Spinner';

export const TodoView = () => {
  const [userData, setUserData] = useState({
    id: '',
    name: '',
  });
  const [loading, setLoading] = useState<boolean>(false);
  const navigate = useNavigate();

  const uploadUser = async () => {
    setLoading(true);
    try {
      const res = await fetch(`http://localhost:3001/login`);
      const data = await res.json();
      console.log(data);                                                 <--- returns users data

      setUserData(data);

      console.log(userData);                                     <---- returns empty objects
    } catch (error) {
      console.log(error);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    uploadUser();
  }, []);

  if (loading) {
    return <Spinner />;
  }

  if (!userData.id || !userData.name) {
    navigate('/');
  }

  return (
    <>
      <NavigationUser id={userData.id} />
      <div className="todos-container">
        <h2>Hello {userData.name}</h2>

        <TodosList userId={userData.id} />                     <-- here is a table
      </div>
    </>
  );
};

Tried to log some data as on screenshot

What’s in TodosList.tsx on line 11? console.log(data)? That would mean that you never get anything from that fetch http://localhost:3001/todo/${userId}, right? What happens if you log userId in TodosList component? That seems to be ok…

TodosList.tsx on line 11 is console.log(todosList)
console.log on userId gives:

Looks like you need to destructure userId because it’s an object:

export const TodosList = ({userId}: any) => { 

ok. I destructured userId and run the app. logs shows at TodosViev , console.log(data) => gives object with data, but
in the same file console.log(userData); throws empty object cod is in snippet in earlier post.

in the todosList file logs throws console.log(userId); → gives userID
and console.log(todosList); throws null,
So i really dont understand why it is happening, the only thing i know it is that something is messed up.
Because if i have access to users id it means i should have access to all data, but i have not

Can you post your current code from TodosList with the consoles again, here?

here is the code and console output:

import { TodoEntity } from 'types';
import { Spinner } from '../../common/Spinner/Spinner';
import { TodosTable } from './TodosTable';
import { AddTodo } from './AddTodo';
import './Todos.css';

export const TodosList = ({ userId }: any) => {
  const [todosList, setTodosList] = useState<TodoEntity[] | null>(null);
  console.log(todosList);

  const refreshTodos = async () => {
    setTodosList(null);
    const res = await fetch(`http://localhost:3001/todo/${userId}`);
    const data = await res.json();
    setTodosList(data.todosList);
  };
  console.log(userId);

  useEffect(() => {
    refreshTodos();
  }, []);

  if (todosList === null) {
    return <Spinner />;
  }
  return (
    <>
      <div>{/* <AddTodo onTodoChange={refreshTodos} userId={userId} /> */}</div>
      <div>
        <h3>Todos:</h3>
        {/* <TodosTable todos={todosList} onTodoChange={refreshTodos} /> */}
      </div>
    </>
  );};```

![qw34ffb|549x500](upload://vDRCrpSx0LX0a2SYnC3VPZxYFE.png)

So. You’re one step further now.
Due to the destructuring of userId, userId is no longer undefined and this http://localhost:3001/todo/${userId} is a valid request now. Now we see a new error because there is something wrong with the response of this request:

const res = await fetch(`http://localhost:3001/todo/${userId}`);

Apparently it’s not a json object, but html.

does it mean that theres something wrong on the backend side. Like something is not parsed into JSON format?