Node Nx Tutorial - Step 2: Display todos
Nx.dev Tutorial | Node | Step 2: Display Todos
Great! We now have a server application set up to show some data when going to the /api
route.
Next, we're going to add a new service, and set up some server side templates.
Creating a todos service
With Nx, we have the ability to scaffold out new code for our application. Let's create a Todos service and populate some todos!
Run nx generate @nrwl/nest:service todo --project todos --directory app
to generate our new service
$ nx generate @nrwl/nest:service todo --project todos --directory app
CREATE apps/todos/src/app/todo/todo.service.spec.ts (453 bytes)
CREATE apps/todos/src/app/todo/todo.service.ts (89 bytes)
UPDATE apps/todos/src/app/app.module.ts (318 bytes)
Services are not the only things that the
@nrwl/nest
plugin can create. Runnx list @nrwl/nest
to see other capabilities that the plugin provides.
Open the newly created file in apps/todos/src/app/todo/todo.service.ts
and paste the following code:
1import { Injectable } from '@nestjs/common';
2
3export type Todo = {
4 message: string;
5 done: boolean;
6};
7
8const todos: Todo[] = [
9 { message: 'Take out trash', done: false },
10 { message: 'Continue using Nx', done: false },
11];
12
13@Injectable()
14export class TodosService {
15 getTodos(): Todo[] {
16 return todos;
17 }
18}
Usually services should call some kind of data source (like a database or even a file) but for our tutorial, we'll just populate todos manually.
We now have our Todos service ready!
Install template engine
In order to render some views, we'll need to install a template engine:
yarn add hbs
or
npm install --save hbs
Once the installation process is complete, we need to configure the main.ts
file with the following code:
1import { Logger } from '@nestjs/common';
2import { NestFactory } from '@nestjs/core';
3import { NestExpressApplication } from '@nestjs/platform-express';
4import { join } from 'path';
5
6import { AppModule } from './app/app.module';
7
8async function bootstrap() {
9 const app = await NestFactory.create<NestExpressApplication>(AppModule);
10
11 app.setBaseViewsDir(join(__dirname, 'assets', 'views'));
12 app.setViewEngine('hbs');
13
14 const port = process.env.PORT || 3333;
15 await app.listen(port, () => {
16 Logger.log('Listening at http://localhost:' + port);
17 });
18}
19
20bootstrap();
We added configuration for setting up the view engine, and removed the globalPrefix
option.
Template rendering
Under the assets
directory of the todo's project, we'll create a views
directory with an index.hbs
file inside with the following content:
1
2<html>
3 <head>
4 <meta charset="utf-8" />
5 <title>App</title>
6 </head>
7
8 <body>
9 <ul class="todos">
10 {{#each todos}}
11 <li><input type="checkbox" {{#if done}}checked{{/if}} /> {{message}}</li>
12 {{/each}}
13 </ul>
14 </body>
15</html>
Next, we'll update the app.controller.ts
file with the following:
1import { Controller, Get, Render } from '@nestjs/common';
2
3import { AppService } from './app.service';
4import { TodosService } from './todos/todos.service';
5
6@Controller()
7export class AppController {
8 constructor(
9 private readonly appService: AppService,
10 private todosService: TodosService
11 ) {}
12
13 @Get('api')
14 getData() {
15 return this.todosService.getTodos();
16 }
17
18 @Get()
19 @Render('index')
20 root() {
21 return {
22 todos: this.getData(),
23 };
24 }
25}
We changed the @Get
decorator for the getData
function to point to the api
route. We also changed this to call the todosService.getTodos()
method.
Then we added the root
function which renders the index
file from our views
directory.
The serve process should still be running. If it isn't, restart the process with
nx serve todos