如何在使用Nest.js拦截器拦截响应后推送数据?

huangapple go评论74阅读模式
英文:

How to push data after response has been intercepted using nest.js interceptors?

问题

我很抱歉,但是你提供的内容已经是代码,因此我将不提供翻译。如果你有其他问题或需要关于这段代码的解释或帮助,请随时提出。

英文:

I am sorry if my request sounds easy but I am very new to nestJs.

The goal of my code I have a problem with is:

  • I enter a physical address through a swagger api.
  • I geolocate this address.
  • I want to save both the address and the geolocation result.

For this,
I have 2 observables that get data through a nestjs interceptor (before saving to database) and would like to push this data into my database. I am using mongoose=>mongoDB.

The points.interceptor.ts code is:

export class PointsInterceptor implements NestInterceptor {
  async intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<any>> {

    var monaddress = context.switchToHttp().getRequest().body
    const geocodeResult = from(geocoder.geocode(monaddress));
    const geoCoder = await lastValueFrom(geocodeResult);
    return next.handle().pipe(
 //     tap(value => console.log(value)),
      map(value => {
        // Returning an object from both next.handle() and geoPremiseToObservable
        return {
          ...value,
          geoCoder: geoCoder
        }
      })
      )
  }

}

What I can see through VSCode debugger is that data is here when excecuting next.handle():
如何在使用Nest.js拦截器拦截响应后推送数据?

The points.schema.ts is:

export const PointSchema = new mongoose.Schema({
  address: String,
  geocoded: Object
});

The create-point.dto.ts is:

export class CreatePointDto {
    readonly address: string;
    readonly geocoded: Object;

The point.service.ts is

@Injectable()
export class PointsService {
  constructor(
    @Inject('POINT_MODEL')
    private PointModel: Model<Point>,
  ) {}

  async create(createPointDto: CreatePointDto): Promise<Point> {
    const createdPoint = new this.PointModel(createPointDto);
    return createdPoint.save();
  }

  async findAll(): Promise<Point[]> {
    return this.PointModel.find().exec();
  }
}
    }

The point.controller.ts is :

export class PointsController {
  constructor(private readonly pointsService: PointsService) {}

  @Post()
  @UseInterceptors(PointsInterceptor)
  create(@Body() createPointDto: CreatePointDto) {
     return this.pointsService.create(createPointDto);
  }

  @Get()
  findAll() {
    return this.pointsService.findAll();
  }
}

Thank you in advance for every help.

答案1

得分: 1

这应该是一个相对简单的任务,但你必须理解拦截器的工作原理。

在拦截器内部,无论你在 return 之前做什么都将在请求进入服务/控制器之前完成,而无论你在 return 之后做什么都将在服务/控制器的生命周期结束后完成。

让我们稍微修改你的拦截器以完成你的工作:

const request = context.switchToHttp().getRequest();
if(request.body) {
  // 我不知道你在控制器中希望如何传递地址的信息,我假设你将其作为字符串传递
  const monaddress = request.body;
  const geocodeResult = from(geocoder.geocode(monaddress));
  const geocoded = await lastValueFrom(geocodeResult);

  // 与你的 create-point.dto 匹配
  request.body = {
    address: monaddress,
    geocoded: geocoded
  }
}

这将修改你的请求体,使其包含解码数据的 geocoded 字段,并可在服务中使用。

英文:

This should be relatively simple task, but you have to understand how interceptor works.

Inside interceptor, whatever you do before return will be done before it goes to the service/controller and whatever you do after return will be done after the lifespan of the service/controller.

Lets change your interceptor a bit to do your work

const request = context.switchToHttp().getRequest();
if(request.body) {
  // I dont have  information how you are expecting the address in the controller, Im assuming you are passing as string
  const monaddress = request.body;
  const geocodeResult = from(geocoder.geocode(monaddress));
  const geocoded = await lastValueFrom(geocodeResult);

  // matching with your create-point.dto
  request.body = {
    address: monaddress
    geocoded: geocoded
  }
}

so this will modify your request body to have the geocoded field with the decoded data and will be available in the service itself

huangapple
  • 本文由 发表于 2023年7月24日 18:53:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76753771.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定