React Todo List

I’ve been trying to output the title(s) of my todo list. Looping through them works fine but I struggle with the titles. VS Enterprise hasn’t been helpful either with its rather cryptic error messages. What am I doing wrong?

TodoApp

import * as React from 'react';
import Todos from './Todos';

export interface ITodoAppProps {
    children?: React.ReactChildren;
}

export class TodoApp extends React.Component<ITodoAppProps> {

    constructor(props: ITodoAppProps) {
        super(props)
    }

    state = {
        todos: [
            {
                id: 1,
                title: "Take out the trash",
                completed: false
            },
            {
                id: 2,
                title: "Clean the dishes",
                completed: false
            },
            {
                id: 3,
                title: "Walk the dog",
                completed: false
            }
        ]
    }

    render() {
        return (
            <Todos todos={this.state.todos}  />
        );
    }
}

export default TodoApp;

Todos

import * as React from 'react';
import TodoItem, { ITodoItemProps } from './TodoItem';

export class Todos extends React.Component<ITodoItemProps> {
    render() {        
        return this.props.todos.map(() => (
            <TodoItem todos={this.props.todos} />
        ));
    }
}

export default Todos;



**TodoItem**

import * as React from 'react';

export interface ITodoItemProps {
    todos?: ITodosItem[];
}

export interface ITodosItem {
    id: number;
    title: string;
    completed: boolean
}

export class TodoItem extends React.Component<ITodoItemProps> {
    render() {

        const todoStyle = {
            padding: "10px",
            background: "#CCC",
            borderBottom: "1px dotted #333",
            
        }

        const checkboxStyle = {
            marginRight: "5px"
        }
        
        return (
            <div style={todoStyle}>
                <input type="checkbox" style={checkboxStyle} />
                {/*{todos.title} {this.props.todos.title}  **<-- problem lies here** */}
                <button className="btn btn-xs btn-danger pull-right">X</button>
            </div>
        );
    }
}

export default TodoItem;

You pass ‘Todos’ array all the way down to ‘TodoItem’ component, and you are trying to access of its title property as if it was an object, which is not the case.

Now, you can access each properties of Todo props, since it is an object.
Such, {this.props.todo.title} …

Thanks for your quick reply Tony. Now I’m getting this error message which I can’t make sense off.

Did you change todos props name as todo inside TodoItem component?

Not sure I understand your question. Are you referring to this:

export interface ITodoItemProps {
    todos?: ITodosItem[];
}

?

After making the change you suggested Todos and TodoItem look like this:

Todos

import * as React from 'react';
import TodoItem, { ITodoItemProps } from './TodoItem';

export class Todos extends React.Component<ITodoItemProps> {
   
    render() {        
        return this.props.todos.map((todo) => (
            <TodoItem todo={todo} />
        ));
    }
}

export default Todos;

TodoItem

import * as React from 'react';

export interface ITodoItemProps {
    todos?: ITodosItem[];
}

export interface ITodosItem {
    id: number;
    title: string;
    completed: boolean
}

export class TodoItem extends React.Component<ITodoItemProps> {
   
    render() {

        const todoStyle = {
            padding: "10px",
            background: "#CCC",
            borderBottom: "1px dotted #333",
            
        }

        const checkboxStyle = {
            marginRight: "5px"
        }
        
        return (
            <div style={todoStyle}>
                <input type="checkbox" style={checkboxStyle} />
                {this.props.todos.title}
                <button className="btn btn-xs btn-danger pull-right">X</button>
            </div>
        );
    }
}

export default TodoItem;

What I meant was,

Simply, you should call it {this.props.todo.title} :slight_smile:

OK, got it. Thank you!