Crea una cuenta o inicia sesión

¡Continúa aprendiendo sin ningún costo! Únete y comienza a potenciar tu carrera

Convierte tus certificados en títulos universitarios en USA

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

19 Días
11 Hrs
32 Min
41 Seg

Interacción entre módulos

4/17
Recursos

Dentro de un módulo, puedes tener la necesidad de utilizar un servicio que pertenece a otro módulo. Importar estos servicios en otros módulos requiere de un paso adicional.

Importaciones de servicios compartidos

Si tienes un Módulo A que posee un Servicio A y un segundo Módulo B requiere hacer uso de este, debes exportar el servicio para que otro módulo pueda utilizarlo.

// Módulo A
import { ServiceA } from './service-A.service';

@Module({
  providers: [ServiceA],
  exports: [ServiceA]
})
export class ModuleA {}
// Módulo B
import { ServiceA } from './module-A/service-A.service';

@Module({
  providers: [ServiceA]
})
export class ModuleB {}

Debes indicar en la propiedad exports del decorador @Module() que un módulo es exportable para que otro módulo pueda importarlo en sus providers.

De esta manera, evitas errores de compilación de tu aplicación que ocurren cuando importas servicios de otros módulos que no están siendo exportados correctamente.

Ejemplo de interacción entre módulos

A continuación, podrás ver el código que necesitas para hacer que los módulos interactúen entre sí.

// src/users/entities/order.entity.ts
import { User } from './user.entity';
import { Product } from './../../products/entities/product.entity';

export class Order { //  // 👈 new entity
  date: Date;
  user: User;
  products: Product[];
}
// src/users/controllers/users.controller.ts
  @Get(':id/orders') //  👈 new endpoint
  getOrders(@Param('id', ParseIntPipe) id: number) {
    return this.usersService.getOrderByUser(id);
  }
// src/users/services/users.service.ts

...
import { Order } from '../entities/order.entity';

import { ProductsService } from './../../products/services/products.service';


@Injectable()
export class UsersService {
  constructor(private productsService: ProductsService) {}
  ...

  getOrderByUser(id: number): Order { // 👈 new method
    const user = this.findOne(id);
    return {
      date: new Date(),
      user,
      products: this.productsService.findAll(),
    };
  }
}
// src/products/products.module.ts

import { Module } from '@nestjs/common';

....

@Module({
  controllers: [ProductsController, CategoriesController, BrandsController],
  providers: [ProductsService, BrandsService, CategoriesService],
  exports: [ProductsService], // 👈 Export ProductsService
})
export class ProductsModule {}
// src/users/users.module.ts
import { Module } from '@nestjs/common';

...

import { ProductsModule } from '../products/products.module';

@Module({
  imports: [ProductsModule], // 👈 Import ProductsModule
  controllers: [CustomerController, UsersController],
  providers: [CustomersService, UsersService],
})
export class UsersModule {}

Contribución creada por: Kevin Fiorentino.

Aportes 18

Preguntas 8

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Para lograr usar el Servicio A que hace parte de Módulo A en el Módulo B debemos exportar el Servicio A y luego importar el  Módulo A en el Módulo B. 😮

Si alguna vez mientras desarrollan en NestJS y se encuentran con que a pesar de estar exportados e importados los módulos/servicios, y Nest les sigue pidiendo que los añadan, seguramente es porque ambos servicios están siendo llamados el uno al otro, en otras palabras, un círculo vicioso. Para esto Nest implementó la siguiente solución:

import { forwardRef } from '@nestjs/common';
import { ModuloUno } from 'modules/moduloUno.module';

@Module({
  imports: [
    forwardRef(() => ModuloUno), // fordwardRef nos ayuda a que ambos servicios sean llamados recíprocamente
  ]})

Recuerden utilizar esto para ambos módulos, y también para ambos servicios.

El fin de la clase es enseñar como se exportan e importan los modulos, pero para fines de logica de negocio, el ejercicio real se haria con la entidad de customer, quienes son lo que clientes que hacen las compras. Ya que users en este caso serian mas como de tipo admin de la tienda.

Interacción entre Módulos

Los módulos funcionan como islas que se encuentran aisladas, cada uno con sus controladores, services etc., en muchos casos vamos a necesitar que nuestros módulos se comuniquen entre si dependiendo de la lógica del negocio

¿Cómo comunicar módulos?

En el siguiente ejemplo vamos a comunicar el modulo de users con el modulo de products

Entities

Para hacer uso de alguna entiti de otro modulo simplemente importamos la clase:

El el siguiente ejemplo exportamos la entidad Product que hace parte del modulo products en nuestra entidad order que hace parte del modulo de user

import { User } from './user.entity';
import { Product } from './../../products/entities/product.entity';

export class Order {
  date: Date;
  user: User;
  products: Product[];
}

Services

Para hacer uso de algún servicio que no haga parte de los servicios de nuestro modulo, lo primero que debemos hacer es importar la clase en nuestro servicio:

En el siguiente ejemplo importamos la clase de ProductService en nuestra clase UserService

import { ProductsService } from './../../products/services/products.service';

Luego debemos instanciarlo en el constructor de nuestra clase utilizando la inyección de dependencias, quedando de la siguiente manera;

constructor(private productsService: ProductsService) {}

Y luego en la clase en la cual necesitamos reutilizar un servicio de otro modulo lo llamamos:

getOrderByUser(id: number): Order {
    const user = this.findOne(id);
    return {
      date: new Date(),
      user,
      products: this.productsService.findAll(),
    };
  }

Si ejecutamos o probamos nuestro servicio, nos aparecerá un error en consola

El error que nos aparece en la terminal, básicamente nos esta diciendo que ProductServices hace parte de un modulo de ProductServices y no de UserServices lo que genera un problema de colisión.

Solución


Para solucionar este problema, debemos primero indicar en nuestro modulo de products que vamos a exportar nuestro productServices y asi cualquier modulo que lo necesite lo pueda utilizar sin ningún problema:

En nuestro products.module.ts:

@Module({
  controllers: [ProductsController, CategoriesController, BrandsController],
  providers: [ProductsService, BrandsService, CategoriesService],
	exports: [ProductsService]
})

y luego en nuestro archivo user.module.ts importamos el modulo:

@Module({
  imports: [ProductsModule],
  controllers: [CustomerController, UsersController],
  providers: [CustomersService, UsersService],
})

Es muy bonito Nest, te hace crecer como dev obligandote a seguir arquitecturas y buenas practicas ❤️

¿Por qué se instancia productsService en el constructor? y como privado? ```js @Injectable() export class UsersService { constructor (private productsService: ProductsService) {} private counterId = 1; private users: User[] = [ { id: 1, email: '[email protected]', password: '12345', role: 'admin', }, ]; ```
C:\Users\nicol\Documents\Cursos\nestjs-modular\src\users\services\users.service.ts:11 constructor(private productsService: ProductsService){} ^ ReferenceError: products\_service\_1 is not defined at Object.\<anonymous> (C:\Users\nicol\Documents\Cursos\nestjs-modular\src\users\services\users.service.ts:11:40) at Module.\_compile (node:internal/modules/cjs/loader:1256:14) at Object.Module.\_extensions..js (node:internal/modules/cjs/loader:1310:10) at Module.load (node:internal/modules/cjs/loader:1119:32) at Function.Module.\_load (node:internal/modules/cjs/loader:960:12) at Module.require (node:internal/modules/cjs/loader:1143:19) at require (node:internal/modules/cjs/helpers:121:18) at Object.\<anonymous> (C:\Users\nicol\Documents\Cursos\nestjs-modular\src\users\controllers\users.controller.ts:12:1) at Module.\_compile (node:internal/modules/cjs/loader:1256:14) at Object.Module.\_extensions..js (node:internal/modules/cjs/loader:1310:10) Esttoyy tenniendo este error al coorrerr el servidor
importaria en modulo de ProductModule en el modulo de UserModule y listo.

Para lograr usar el Servicio A que hace parte de Módulo A en el Módulo B debemos exportar el Servicio A y luego importar el Módulo A en el Módulo B. 😮

Para los que han trabajado con Angular, se les va a facilitar entender como usar este framework.

Es primera vez en todos los cursos del Platzi que la consola me da el mismo error que el profesor _

Si ya tienes práctica con los módulos de angular, se te hará muy familiar esta manera de trabajar, creo que es muy parecido, sino que igual, incluso los nombres de los arrays de los módulos, excepto por el de controllers, y en angular esta el de declarations.

Se parece mucho a Angular 😮

Exportando un servicio de un módulo para que sea utilizado en otro módulo

crear nuevo endpoint con base al iduser traiga sus orders (ordenes de compra)

Las entidades son solo clases donde utilizaremos sus controlller, otros modules y services , no la entidad como tal

Crear una nueva entidad importando módulos

👏