Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I'm trying to do what I think it's a stupid simple endpoint and some how it seems nestjs is not resolving the observable from Axios which results in the request hanging until it reaches the timeout.
I've stripped down my entire application to barebones, literally, in the pursuit of the issue and I still can't really find anything....
main.ts:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(8080);
bootstrap();
app.module.ts:
import { Module } from '@nestjs/common';
import { AuthModule } from './auth/authModule';
@Module({
imports: [AuthModule],
export class AppModule {}
AuthModule.ts:
import { Module } from '@nestjs/common';
import { AuthController } from './controllers/auth.controller';
import { HttpModule } from '@nestjs/axios';
@Module({
controllers: [AuthController],
imports: [HttpModule],
export class AuthModule {}
Auth.controller.ts:
import { Controller, Post } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { Observable } from 'rxjs';
import { AxiosResponse } from 'axios';
@Controller('auth')
export class AuthController {
constructor(private httpService: HttpService) {}
@Post('/login')
login(): Observable<AxiosResponse<string>> {
console.log('hit');
return this.httpService.get<string>('http://auth-ms/health');
package.json:
"dependencies": {
"@liaoliaots/nestjs-redis": "^8.2.1",
"@metamask/eth-sig-util": "^4.0.0",
"@nestjs/axios": "^0.0.8",
"@nestjs/common": "^8.0.0",
"@nestjs/config": "^2.0.0",
"@nestjs/core": "^8.0.0",
"@nestjs/platform-express": "^8.0.0",
"@nestjs/typeorm": "^8.1.4",
"axios": "^0.27.2",
"faker": "^6.6.6",
"ioredis": "^5.0.3 || ^0.3.6",
"jsonwebtoken": "^8.5.1",
"jwt-decode": "^3.1.2",
"nestjs-ethers": "^1.0.1",
"nestjs-real-ip": "^2.1.0",
"pg": "^8.7.3",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0",
"typeorm": "^0.3.6",
Any clue on what's going on here? I guess I'm missing something small and stupid but... can't really figure out what.
So, AxiosResponse is a complex data structure and contains circular dependencies.
So you need to map it because you can't return it like this (except if you use a lib that parse circular JSON)
So you need to map the observable to only get the data of the website.
@Post('/login')
login(): Observable<string> {
console.log('hit');
return this.httpService
.get<string>('http://auth-ms/health')
.pipe(map((v) => v.data));
–
The Observable class works like a Promise and it handles I/O commands asynchronously by default. To return the result from a gateway request, like you are trying to do, you'll need to resolve the Observable synchronously.
To do it, you need to use the firstValueFrom
or lastValueFrom
functions from rxjs
lib to convert it to a Promise and await
the response:
import { Controller, Post } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { Observable, firstValueFrom } from 'rxjs';
import { AxiosResponse } from 'axios';
@Controller('auth')
export class AuthController {
constructor(private httpService: HttpService) {}
@Post('/login')
async login(): Promise<string> {
const responseObserver = this.httpService.get<string>('http://auth-ms/health');
const response = await firstValueFrom(responseObserver);
return response.data;
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.