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.
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.
In the TodoService
, we'll create a create
method that:
- Accepts a
title
, adueDate
(required), and an optionaldescription
. - Creates a new
Todo
item with a unique ID usingDate.now()
. - Adds the new item to the existing list of ToDo items and returns a success message.
Here's how this method is implemented:
TypeScript1import { 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.
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
, anddescription
from the form using the@Body
decorator. - Call the
create
method from theTodoService
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:
TypeScript1import { 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 thecreate
method inTodoService
. - After creating the new item, it returns the updated list of ToDo items along with a success message using the
@Render('index')
decorator.
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, XML1<!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 aPOST
request to/todos
when the user submits it. - The form contains fields for
title
,dueDate
, and an optionaldescription
. - The "Add ToDo" button submits the form, triggering the
create
method in theTodoController
.
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.
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!