Reputation: 81
I'm trying to implement node.js Spotify Authorization flow in NestJs.
But HttpService Post and Get functions doesn't work as in node.js.
Node.js working example:
var request = require('request'); // "Request" library
app.get('/callback', function(req, res) {
var authOptions = {
url: 'https://some-url.com/api/token',
form: {
code: code,
redirect_uri: redirect_uri,
grant_type: 'authorization_code'
},
headers: {
'Authorization': 'Basic ' + (Buffer.from(client_id + ':' + client_secret).toString('base64'))
},
json: true
};
// I'm trying to implement this post in NestJS
request.post(authOptions, function(error, response, body) {
var options = {
url: 'https://api.spotify.com/v1/me',
headers: { 'Authorization': 'Bearer ' + access_token },
json: true
};
request.get(options, function(error, response, body) {
console.log(body);
});
}
I'm using HttpService Post method in NestJS and that doesn't work:
constructor(private httpService: HttpService) {}
@Get('callback')
callback(@Request() req, @Res() res): any {
let code = req.query.code || null;
const url = 'https://some-url.com/api/token';
const form = {
code: code,
redirect_uri: this.redirect_uri,
grant_type: 'authorization_code'
}
const headers = {
'Authorization': 'Basic ' + (Buffer.from(this.client_id + ':' + this.client_secret))
}
// doesn't work
this.httpService.post( url, form, { headers: headers }).pipe(
map((response) => {
console.log(response);
}),
);
}
Upvotes: 0
Views: 2229
Reputation: 589
Add this imports to the controller:
import { Observable } from 'rxjs';
import { take, tap, map } from 'rxjs/operators';
Then try this:
constructor(private httpService: HttpService) {}
@Get('callback')
callback(@Request() req, @Res() res): Observable<any> {
let code = req.query.code || null;
const url = 'https://some-url.com/api/token';
const form = {
code: code,
redirect_uri: this.redirect_uri,
grant_type: 'authorization_code'
}
const headers = {
'Authorization': 'Basic ' + (Buffer.from(this.client_id + ':' +
this.client_secret))
}
return this.httpService.post( url, form, { headers: headers }).pipe(
// Take first result to complete the observable..
take(1),
// [OPTIONAL] Some debug log to see the response.
tap((response: { data: any }) => {
console.log(`Response: ${JSON.stringify(response.data)}`);
})
// Map the response object to just return its data.
map((response: { data: any }) => response.data),
);
}
Upvotes: 0
Reputation: 331
In NestJS, you do not need to send req, res object to your function parameter. Nest Js provide build-in decorator for req.body
, req.query
and req.param
as @Body
, @Query
, and @Param
. I write down to call post method and get method. You can also use put, patch, delete, and other methods. Please make a data transfer object file in your module.
for further reference, you can check this: https://docs.nestjs.com/controllers
export class yourController {
constructor(private readonly httpService: HttpService) {}
@Post('your-route-name')
public postMethod(@Body() yourDTO: YourDTOClass): Promise<interface> {
try {
return this.httpService.method(yourDTO);
} catch (err) {
throw new HttpException(err, err.status || HttpStatus.BAD_REQUEST);
}
}
@Get('your-route-name')
find(@Query() query: QueryDTO): Promise<interface> {
try {
return this.httpService.methodName(query);
} catch (err) {
throw new HttpException(err, err.status || HttpStatus.BAD_REQUEST);
}
}
}
Upvotes: 2
Reputation: 3405
You should prefix your controller with "async" and use "await" followed by "toPromise()"...
constructor(private httpService: HttpService) {}
@Get('callback')
async callback(@Request() req, @Res() res): any {
// ... remaining code here
const response =
await this.httpService.post(url, form, { headers: headers }).toPromise();
return response;
}
Upvotes: 0
Reputation: 468
You should put return
before this.httpService.post(...)
. Normally you would have to subscribe to the Observable returned by the post method but NestJS handles this for you through the @Get() decorator.
Upvotes: 0