Search code examples
nestjsinterceptor

nestjs: inject data from service to interceptor


I have services like this

async create(dto: MyDTO): Promise<MyEntity> {
    const data = this.repository.create(dto);
    return this.repository.save(data );
}

and I have an interceptor like this:

@Injectable()
export class MyInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler<any>): Observable<any> | Promise<Observable<any>> {    
    return next.handle().pipe(
      map(data => {
        return {
          Error: false,
          data
        };
      }),
    );
  }
}

I want to pass the message from the service to the interceptor like this

async create(dto: MyDTO): Promise<MyEntity> {
    const data = this.repository.create(dto);
    let message ="insert successful"
    return this.repository.save(data );
}

and in my interceptor use it like this

@Injectable()
export class MyInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler<any>): Observable<any> | Promise<Observable<any>> {    
    return next.handle().pipe(
      map(data => {
        return {
          Error: false,
          data,
          message
        };
      }),
    );
  }
}

What should I do?


Solution

  • You can try something along these lines, assuming your controller is like this:

    @Post()
    async create(@Body(new ValidationPipe()) body: MyDto)  
    {
      return this.myEntityService.createOrganisation(body);
    }
    

    Create a new model extending the Request model, like this:

    export interface ExtendedRequestModel extends Request {
      successMessage: string
    }
    

    Fetch the request object in the controller and pass it to the service layer.

    @Post()
    async create(@Body(new ValidationPipe()) body: MyDto, @Req() request: ExtendedRequestModel)  
    {
      return this.myEntityService.createOrganisation(body, request);
    }
    
    async create(dto: MyDTO, request: ExtendedRequestModel): Promise<MyEntity> {
        const data = this.repository.create(dto);
        request.successMessage ="insert successful";
        return this.repository.save(data);
    }
    
    @Injectable()
    export class MyInterceptor implements NestInterceptor {
      intercept(context: ExecutionContext, next: CallHandler<any>): Observable<any> | Promise<Observable<any>> {
        let req: ExtendedRequestModel;
        req = context.switchToHttp().getRequest();    
        return next.handle().pipe(
          map(data => {
            return {
              error: false,
              message: req.successMessage,
              data
            };
          }),
        ).pipe(catchError((err) => {
           throwError(() => new InternalServerErrorException(err))
       }));
      }
    }
    

    It's not tested, hopefully, you got the idea.