Node Nx Tutorial - Step 2: Display todos
Great! you now have a server application set up to show some data when going to the /api
route.
Next, you're going to add a new service, and set up some server side templates.
Creating a todos service
With Nx, you have the ability to scaffold out new code for your application. 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 todos --project todos --directory app
CREATE apps/todos/src/app/todos/todos.service.spec.ts (453 bytes)
CREATE apps/todos/src/app/todos/todos.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. Run nx list @nrwl/nest
to see other capabilities that the plugin provides.
Open the newly created file in apps/todos/src/app/todos/todos.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}
19
Usually services should call some kind of data source (like a database or even a file) but for this tutorial, just populate todos manually.
You now have your Todos service ready!
Install template engine
In order to render some views, you need to install a template engine:
yarn add hbs
Once the installation process is complete, you 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();
21
You added configuration for setting up the view engine, and removed the globalPrefix
option.
Template rendering
Under the assets
directory of the todo's project, you 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>
16
Next, 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}
26
You changed the @Get
decorator for the getData
function to point to the api
route. You also changed this to call the todosService.getTodos()
method.
Then you 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
What's Next
- Continue to Step 3: Share code