Lesson 3
Creating New ToDo Items
Creating New ToDo Items

Welcome back! Now that you’ve set up a basic ToDo list, it's time to add functionality that allows users to create new items. This step enables direct interaction with the application by adding new tasks to the ToDo list.

By the end of this lesson, you'll have a form for users to input and create new ToDo items, with server-side handling to store them.

What This Lesson Covers

In this lesson, you'll learn how to:

  • Extend your TodoService to allow the creation of new ToDo items.
  • Update your TodoController to handle form submissions.

These enhancements will make your ToDo app interactive, allowing users to add new items directly through the interface.

Enhancing the Todo Service

In the TodoService, we'll create a create method that:

  • Accepts a title, a dueDate (required), and an optional description.
  • Creates a new Todo item with a unique ID using Date.now().
  • Adds the new item to the existing list of ToDo items and returns a success message.

Here's how this method is implemented:

TypeScript
1import { Injectable } from '@nestjs/common'; 2import { Todo } from './todo.model'; 3 4@Injectable() 5export class TodoService { 6 private todos: Todo[] = [ 7 new Todo(1, 'Learn NestJS', '2023-09-01', 'Explore the basics of NestJS'), 8 new Todo(2, 'Develop MVC App', '2023-10-01', 'Build an application using the MVC pattern'), 9 new Todo(3, 'Study Node.js', '2023-11-01', 'Deep dive into Node.js fundamentals'), 10 new Todo(4, 'Review TypeScript', '2023-12-01', 'Brush up on TypeScript essentials') 11 ]; 12 13 findAll(): Todo[] { 14 return this.todos; 15 } 16 17 create(title: string, dueDate: string, description?: string): string { 18 const todo = new Todo(Date.now(), title, dueDate, description); // Using Date.now() for ID 19 this.todos.push(todo); 20 return 'ToDo created successfully!'; 21 } 22}

The create method in the TodoService adds the new item to the todos array and returns a success message.

Updating the Todo Controller

Next, let's update the TodoController to handle form submissions. This will allow the app to process data entered by users and add new items to the ToDo list.

The create method in the controller will:

  • Listen for POST requests when a user submits a form.
  • Extract the title, dueDate, and description from the form using the @Body decorator.
  • Call the create method from the TodoService to add the new item to the list.
  • Use the @Render('index') decorator to re-render the updated list with a success message.

Here's how to implement this:

TypeScript
1import { Controller, Get, Post, Body, Render } from '@nestjs/common'; 2import { TodoService } from './todo.service'; 3 4@Controller('todos') 5export class TodoController { 6 constructor(private readonly todoService: TodoService) {} 7 8 @Get() 9 @Render('index') 10 findAll() { 11 const todos = this.todoService.findAll(); 12 return { title: 'ToDo List', todos }; 13 } 14 15 @Post() 16 @Render('index') 17 create(@Body() body) { 18 const message = this.todoService.create(body.title, body.dueDate, body.description); 19 return { message, todos: this.todoService.findAll() }; 20 } 21}

In this controller:

  • The @Post() method listens for form submissions.
  • The @Body decorator extracts the form data, passing it to the create method in TodoService.
  • After creating the new item, it returns the updated list of ToDo items along with a success message using the @Render('index') decorator.
Modifying the View with a Form

Finally, let's add a basic form to the view that allows users to create new ToDo items. This form will send a POST request to the controller when submitted.

Here's how to include the form in index.hbs:

HTML, XML
1<!DOCTYPE html> 2<html> 3<head> 4 <title>{{title}}</title> 5</head> 6<body> 7 <h1>ToDo App</h1> 8 <div> 9 <h2>Create New ToDo</h2> 10 <form action="/todos" method="post"> 11 <div> 12 <input type="text" name="title" placeholder="Title" required /> 13 </div> 14 <div> 15 <input type="date" name="dueDate" placeholder="Due Date" required /> 16 </div> 17 <div> 18 <input type="text" name="description" placeholder="Description" /> 19 </div> 20 <div> 21 <button type="submit">Add ToDo</button> 22 </div> 23 </form> 24 </div> 25 26 {{#if message}} 27 <p>{{message}}</p> 28 {{/if}} 29 30 <ul> 31 {{#each todos}} 32 <li>{{this.title}} - {{this.description}} - Due: {{this.dueDate}}</li> 33 {{/each}} 34 </ul> 35 36 {{{body}}} 37</body> 38</html>

In this view:

  • The <form> sends a POST request to /todos when the user submits it.
  • The form contains fields for title, dueDate, and an optional description.
  • The "Add ToDo" button submits the form, triggering the create method in the TodoController.

When the form is submitted, the TodoController processes the data, adds the new item to the list, and displays a success message along with the updated list.

Why This Matters

Adding a "Create" functionality is crucial for building dynamic, interactive applications. It allows users to interact with the app and modify its content directly. With this implementation, your ToDo app becomes a more engaging and practical tool.

By implementing this feature, you've learned how to handle form submissions, process data on the server side, and update the UI to reflect changes. Ready to try it out? Run the code and create some ToDo items!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.