Search code examples
typescriptrxjsnestjs

How to merge 2 Observables in nestjs Interceptor()?


I am developping a nestjs interceptor to geolocate an address I am sending throught a rest API. Here is the code:

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

    var monaddress = context.switchToHttp().getRequest().body
    const geoPremiseToObservable = from(geocoder.geocode(monaddress));
    geoPremiseToObservable.subscribe(value => console.log(JSON.stringify(value)));

    return next.handle().pipe(map(value => console.log(value)))
  }

}

The result of this code is:

  • a JSON coming from the http response:
{
  address: '123, avenue des Champs Elysées, 75008 PARIS',
  _id: new ObjectId("64bd089088f925780705bbbd"),
  __v: 0
}
  • An Object coming from geoCoder
[{"latitude":48.872438,"longitude":2.29811,"state":"75, Paris, Île-de-France","city":"Paris","zipcode":...}]

My wish is to have all of this concatenated in one JSON that will be "pushed to the database". I tried to apply a merge or even a mergeWith. In vain.

Any help would be greatly appreciated.

Thank You.


Solution

  • Can you try tap, like this, so instead of subscribing , get using from and then tap both. Apologies if this does not work, it is not tested

    export class PointsInterceptor implements NestInterceptor {
      intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
        const 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 => {
            //1: Returning an object from both next.handle() and geoPremiseToObservable
            return {
              httpResponse: value,
              geoCoder: geoCoder
            };
    
           //2: Returning an single object by merging the geocoder response with http response
            return {
              ...value,
              geoCoder: geoCoder
            };
          })
        );
      }
    }