Angular Nx Tutorial - Step 7: Share Code

Nx.dev Tutorial | Angular | Step 7: Share Code

Awesome! The application is working end to end! However, there is a problem. Both the backend and the frontend define the Todo interface. The interface is in sync now, but in a real application, over time, it will diverge, and, as a result, runtime errors will creep in. You should share this interface between the backend and the frontend. In Nx, you can do this by creating a library.

Run the following generator to create a library:

npx nx g @nrwl/workspace:lib data

The result should look like this:

myorg/
├── apps/
│   ├── todos/
│   ├── todos-e2e/
│   └── api/
├── libs/
│   └── data/
│       ├── src/
│       │   ├── lib/
│       │   │   └── data.ts
│       │   └── index.ts
│       ├── jest.conf.js
│       ├── tsconfig.app.json
│       ├── tsconfig.json
│       ├── tsconfig.spec.json
│       └── tslint.json
├── workspace.json
├── nx.json
├── package.json
├── tools/
├── tsconfig.base.json
└── tslint.json

Copy the interface into libs/data/src/lib/data.ts.

1export interface Todo {
2  title: string;
3}

A note about VS Code :

If you're using VS Code it may be necessary at this point to restart the TS server so that the new @myorg/data package is recognised. This may need to be done every time a new workspace library is added.

Refactor the API

Now update apps/api/src/app/app.service.ts to import the interface:

1import { Injectable } from '@nestjs/common';
2import { Todo } from '@myorg/data';
3
4@Injectable()
5export class AppService {
6  todos: Todo[] = [{ title: 'Todo 1' }, { title: 'Todo 2' }];
7
8  getData(): Todo[] {
9    return this.todos;
10  }
11
12  addTodo() {
13    this.todos.push({
14      title: `New todo ${Math.floor(Math.random() * 1000)}`,
15    });
16  }
17}

Update the Angular Application

Next import the interface in apps/todos/src/app/app.component.ts:

1import { Component } from '@angular/core';
2import { HttpClient } from '@angular/common/http';
3import { Todo } from '@myorg/data';
4
5@Component({
6  selector: 'myorg-root',
7  templateUrl: './app.component.html',
8  styleUrls: ['./app.component.css'],
9})
10export class AppComponent {
11  todos: Todo[] = [];
12
13  constructor(private http: HttpClient) {
14    this.fetch();
15  }
16
17  fetch() {
18    this.http.get<Todo[]>('/api/todos').subscribe((t) => (this.todos = t));
19  }
20
21  addTodo() {
22    this.http.post('/api/addTodo', {}).subscribe(() => {
23      this.fetch();
24    });
25  }
26}

Every time you add a new library, you have to restart npx nx serve. So restart both npx nx serve api and npx nx serve todos and you should see the application running.