nx/docs/shared/node-tutorial/02-display-todos.md
2022-03-16 18:22:54 +00:00

152 lines
4.1 KiB
Markdown

# Node Nx Tutorial - Step 2: Display todos
<iframe loading="lazy" width="560" height="315" src="https://www.youtube.com/embed/I4-sO2LeVbU" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; fullscreen"></iframe>
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**
```bash
$ 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. Run `nx 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:
```typescript
import { Injectable } from '@nestjs/common';
export type Todo = {
message: string;
done: boolean;
};
const todos: Todo[] = [
{ message: 'Take out trash', done: false },
{ message: 'Continue using Nx', done: false },
];
@Injectable()
export class TodosService {
getTodos(): Todo[] {
return todos;
}
}
```
> 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:
```bash
yarn add hbs
```
or
```bash
npm install --save hbs
```
Once the installation process is complete, you need to configure the `main.ts` file with the following code:
```typescript
import { Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { AppModule } from './app/app.module';
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.setBaseViewsDir(join(__dirname, 'assets', 'views'));
app.setViewEngine('hbs');
const port = process.env.PORT || 3333;
await app.listen(port, () => {
Logger.log('Listening at http://localhost:' + port);
});
}
bootstrap();
```
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:
```handlebars
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>App</title>
</head>
<body>
<ul class="todos">
{{#each todos}}
<li><input type="checkbox" {{#if done}}checked{{/if}} /> {{message}}</li>
{{/each}}
</ul>
</body>
</html>
```
Next, update the `app.controller.ts` file with the following:
```typescript
import { Controller, Get, Render } from '@nestjs/common';
import { AppService } from './app.service';
import { TodosService } from './todos/todos.service';
@Controller()
export class AppController {
constructor(
private readonly appService: AppService,
private todosService: TodosService
) {}
@Get('api')
getData() {
return this.todosService.getTodos();
}
@Get()
@Render('index')
root() {
return {
todos: this.getData(),
};
}
}
```
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](/node-tutorial/03-share-code)