Nx Workshop
← Back to lessons

Lesson 4Nx working together

In this section, we create a new library to shared the DTO types to have a single source of truth.

The first step is creating a new agnostic framework library that contains the share types.

> npm run nx -- generate @nrwl/workspace:library --name=api-interfaces --directory=hero

libs/hero/api-interfaces/src/lib/hero-api-interfaces.ts

export type HeroDTO = {
id: string;
name: string;
image: string;
powerstats: {
intelligence: number;
strength: number;
speed: number;
durability: number;
power: number;
combat: number;
};
};

libs/hero/controllers/src/lib/controllers/hero-controller/hero-controller.controller.ts

import { Controller, Get } from '@nestjs/common';
import { HeroDTO } from '@flowing/hero/api-interfaces';
@Controller('hero')
export class HeroControllerController {
private heros: HeroDTO[] = [
{
id: '732',
name: 'Ironman',
powerstats: {
intelligence: 100,
strength: 85,
speed: 58,
durability: 85,
power: 100,
combat: 64,
},
image: 'https://www.superherodb.com/pictures2/portraits/10/100/85.jpg',
},
{
id: '332',
name: 'Hulk',
powerstats: {
intelligence: 88,
strength: 100,
speed: 63,
durability: 100,
power: 98,
combat: 85,
},
image: 'https://www.superherodb.com/pictures2/portraits/10/100/83.jpg',
},
{
id: '149',
name: 'Captain America',
powerstats: {
intelligence: 69,
strength: 19,
speed: 38,
durability: 55,
power: 60,
combat: 100,
},
image: 'https://www.superherodb.com/pictures2/portraits/10/100/274.jpg',
},
];
@Get()
public get(): Promise<HeroDTO[]> {
return Promise.resolve(this.heros);
}
}

apps/hero-app/src/app/app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http'; // <-- add
import { HeroUiModule } from '@flowing/hero/ui';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, HttpClientModule, HeroUiModule], // <-- update with HttpClientModule
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}

libs/hero/data-access/src/lib/services/hero-api.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { HeroDTO } from '@flowing/hero/api-interfaces';
@Injectable({
providedIn: 'root',
})
export class HeroApiService {
constructor(private http: HttpClient) {}
getHeros(): Observable<HeroDTO[]> {
return this.http.get<HeroDTO[]>('/api/hero');
}
}

libs/hero/ui/src/lib/components/hero-viewer/hero-viewer.component.ts

import { Component, Input } from '@angular/core';
import { HeroDTO } from '@flowing/hero/api-interfaces';
@Component({
selector: 'flw-hero-viewer',
template: `
<div class="card">
<img [src]="hero.image" class="card-img-top" [alt]="hero.name" />
<div class="card-body">
<div class="card-text">
<b>{{ hero.name }}</b>
<ul>
<li>Intelligence: {{ hero.powerstats.intelligence }}</li>
<li>Strength: {{ hero.powerstats.strength }}</li>
<li>Speed: {{ hero.powerstats.speed }}</li>
<li>Durability: {{ hero.powerstats.durability }}</li>
<li>Power: {{ hero.powerstats.power }}</li>
<li>Combat: {{ hero.powerstats.combat }}</li>
</ul>
</div>
</div>
</div>
`,
styles: [
`
ul {
padding: 0;
}
ul li {
list-style-type: none;
}
`,
],
})
export class HeroViewerComponent {
@Input() hero: HeroDTO;
}

Now we need to add a configuration that proxies our http request in dev mode. The first step is add the next file

apps/hero-app/proxy.conf.json

{
"/api": {
"target": "http://localhost:3333",
"secure": false
}
}

and the second step is add the next configuration in the workspace.json

...
"serve": {
"executor": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "hero-app:build",
"proxyConfig": "apps/hero-app/proxy.conf.json" // <--
},
"configurations": {
"production": {
"browserTarget": "hero-app:build:production"
}
}
},
...

To see the result, run two different terminal with the next commands

npm run nx serve hero-app
npm run nx serve hero-api

Navigate to the hero-app so you can see how the angular app fetching data from the hero-api app