how to send GET request with parameter - node.js

I'm building a simple MEAN application, but facing some problem with a GET method.
I inserted some data in my mongo collection, now I want to GET all results passing it's Id as parameter, but angular is returning me the following:
I've searched about headers and httpParams, but can't seem to find a solution.
I tested on postman as well, using Get and passing a body as JSON, and it worked, I'm facing trouble sending it's body from angular
here's my code:
Angular service
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '#angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class WebService {
public api = "http://localhost:3000/";
//NODE API
public getRate(param: any){
console.log(param);
return this.http.get(this.api + "api/rate", {_id: param})
}
}
NodeJs function
module.exports.countVotes = function(req, res) {
console.log(req.body._id);
VoteModel.find({movie_id: req.body._id}, (err, rate) => {
if(err){
console.log('rate not found', err)
return res.status(404).json({
message: 'failed to get movie rate'
})
} else {
res.status(200).json(rate);
console.log(rate);
}
})
}
Node returns me req.body as undefined when called.
What am I missing? please someone help me.

It doesn't work because GET requests don't have request body. You can try use POST request with request body or pass the id to GET request as request param or as path variable.

You must pass an instance of HttpPrams in http.get -
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '#angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class WebService {
public api = "http://localhost:3000/";
//NODE API
public getRate(param: any){
let params = new HttpParams().set('_id', param);
console.log(param);
return this.http.get(this.api + "api/rate", { params: params })
}
}

Related

http GET request is not sending to the Node Js API in Angular 13

I developed a Node Js API with express and MongoDB. I wanted to fetch data from the database by using Angular front-end. I created a service to call the GET http request from the from-end with a parameter and the getPatient method was called. But the request is not sending to the end point. I opened the inspect and directed to the network and there was no record of a sent request. But when I send the post method to save data to the database , it has worked.. How can I fix this ?
import { Injectable } from '#angular/core';
import {HttpClient} from "#angular/common/http";
import {environment} from "../../environments/environment";
import {Observable} from "rxjs";
#Injectable({
providedIn: 'root'
})
export class PatientService {
baseURL=environment.baseUrl;
constructor(private http:HttpClient) { }
savePatient(name:string , email:string , dob:string , address:string , contact:string , diagnosis:string):Observable<any>{
return this.http.post(this.baseURL + 'patient/save' , {
name:name,
email:email,
dob:dob,
address:address,
contact:contact,
diagnosis:diagnosis
})
}
getPatient(name:string):Observable<any>{
console.log('service called');
return this.http.get<any>(this.baseURL + 'patient/get' , {headers : {name : name}});
}
}

Property 'json' does not exist on type 'Object'.ts(2339)

I am building a MEAN Stack messaging app. I am trying to retrieve a response from my backend as such but get the following error:
"Property 'json' does not exist on type 'Object'.ts(2339)"
The problem in the below code is the 'json' part of res.json()
import { HttpClient } from "#angular/common/http";
import {Injectable} from '#angular/core';
import { HttpClient } from "#angular/common/http";
import {Injectable} from '#angular/core';
#Injectable()
export class ApiService {
constructor (private httpClient : HttpClient ){}
messages = []
getMessage(){
this.httpClient.get('http://localhost:3000/posts').subscribe(res =>{
//FIX AT LATER STAGE should be this.messages = res.json()
this.messages = res.json();
})
}
}
Here is the situation with Angular:
HttpModule (< Angular 4.3*)
import { HttpModule, Http } from '#angular/http';
Old and deprecated
JSON responses need to manually parsed: res.json()
HttpClientModule (Angular 4.3+)
import { HttpClientModule, HttpClient } from '#angular/common/http';
Current (LTS)
JSON responses are already parsed. res.json() is not required.
* I might be a little off with the version number. Please check the changelog.

How use Nodejs Localstorage (scratch) with Angular

So I have a stored a token in a file "scratch" inside the assets of angular. I would like to use it in SpotifyService ti finally be authenticated but I dont know how angular can search my file and use it as a token:
Node Js
if (typeof localStorage === "undefined" || localStorage === null) {
var LocalStorage = require('node-localstorage').LocalStorage;
localStorage = new LocalStorage('./src/assets/scratch');
}
...
app.get('/auth/spotify/callback',
passport.authenticate('spotify',{failureRedirect:'/auth/error'}),
function(req,res){
const monToken=localStorage.getItem('token');
res.redirect('/');
})
Angular
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { Injectable } from '#angular/core';
import {} from 'rxjs';
import { JwtHelperService } from "#auth0/angular-jwt";
#Injectable({
providedIn: 'root'
})
export class SpotifyService {
constructor(private http:HttpClient,private jwt:JwtHelperService) {
}
isAuthenticated() : Boolean {
let token=localStorage.getItem('token');
return (token != null && !this.jwt.isTokenExpired(token));
}
setTokenHeader(){
let devant: HttpHeaders=new HttpHeaders();
//devant.append('Content-Type', 'application/json');
let authToken=localStorage.getItem('token');
devant.append('Authorization', `Bearer ${authToken}`);
return devant;
}
private header: HttpHeaders = this.setTokenHeader();
Basically, I don't know how can I use the file 'token' inside. If there's another method to store the token in the API please wirte it bellow
you are doing it all wrong...
why do you wanna store the token in nodejs local storage...?
you don't have to store it just verify the token is valid or not which is passed from the cliend who has saved it

Angular 8 - cannot get httpClient POST to do its work maybe in conjunction with Socket.io?

I had a working AngularJS Frontend and a backend written in node.js' express, http and socket.io. Now I want to translate the frontend to Angular 8 and further use the old backend (because it worked well and was a ton of work).
Now I use ngx-socket-io for the chat communication and want to use the HttpClientModule of Angular for the API-requests.
app.module.ts
...
import { HttpClientModule } from '#angular/common/http';
import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';
...
const apiConfig: SocketIoConfig = { url: 'http://localhost:8000', options: {} };
#NgModule({declarations: [...], imports: [
...
HttpClientModule,
SocketIoModule.forRoot(apiConfig)
]
...
login.component.ts
import { CommunicationService } from '../services/communication.service';
...
constructor(
...
private comm: CommunicationService
) { }
submitForm() {
const formValue = this.loginGroup.value;
this.comm.checkAuthentication(formValue.userName, formValue.password);
}
communication.service.ts
import { Socket } from 'ngx-socket-io';
import { HttpClient, HttpErrorResponse } from '#angular/common/http';
...
#Injectable({
providedIn: 'root'
})
export class CommunicationService {
private api = 'http://localhost:8001/api';
constructor(private socket: Socket, private http: HttpClient) { }
checkAuthentication(username: string, password: string) {
console.log(`send: ${username}, ${password}`);
const test = this.http.post<any>(
`${this.api}/authenticate`,
{ username, password }
).pipe(
catchError(this.errorHandler)
);
console.log(test);
const test2 = this.http.get(
`${this.api}/users`
);
console.log(test2);
}
...
}
I can see the request going out, but on the server side it doesn't arrive. I would see a log entry there. If I use postman I see the request arriving, so the server still works.
I could imagine that angular has a problem with the constantly open connection on port 8000 to the socket.io and then use the same socket to throw a request on. Could that be? And yes, the site uses a chat (works on sockets) and some other features that work by api requests. So I need both options working together.
edit: I changed the port of the api to 8001 and it still gets no response. The console.log shows a nearly complete empty object:
{…}
​_isScalar: false
​operator: Object { selector: errorHandler()
, caught: {…} }
​source: Object { _isScalar: false, source: {…}, operator: {…} }
Http client returns an observable so You have to subscribe on it to catch the data , please check this ref
this.http.post<any>(
`${this.api}/authenticate`,
{ username, password }
).pipe(
catchError(this.errorHandler)
).subscribe((data) => {
console.log(data)
});
Before you can actually send the httpclient request you need to subscribe to the returned observable from the post() and get() methods. Change your checkAuthentication() method as follows:
checkAuthentication(username: string, password: string) {
console.log(`send: ${username}, ${password}`);
this.http.post<any>(
`${this.api}/authenticate`,
{ username, password }
).pipe(
catchError(this.errorHandler)
).subscribe((data) => {
console.log(data)
});
this.http.get(
`${this.api}/users`
).subscribe((data) => {
console.log(data)
});
}

I'm using a passport-jwt auth strategy in my nestJS app (with authGuard), how to get access to the token payload in my controller?

I'm trying to get access to the jwt payload in a route that is protected by an AuthGuard.
I'm using passport-jwt and the token payload is the email of the user.
I could achieve this by runing the code bellow:
import {
Controller,
Headers,
Post,
UseGuards,
} from '#nestjs/common';
import { JwtService } from '#nestjs/jwt';
import { AuthGuard } from '#nestjs/passport';
#Post()
#UseGuards(AuthGuard())
async create(#Headers() headers: any) {
Logger.log(this.jwtService.decode(headers.authorization.split(' ')[1]));
}
I want to know if there's a better way to do it?
Your JwtStrategy has a validate method. Here you have access to the JwtPayload. The return value of this method will be attached to the request (by default under the property user). So you can return whatever you need from the payload here:
async validate(payload: JwtPayload) {
// You can fetch additional information if needed
const user = await this.userService.findUser(payload);
if (!user) {
throw new UnauthorizedException();
}
return {user, email: payload.email};
}
And then access it in you controller by injecting the request:
#Post()
#UseGuards(AuthGuard())
async create(#Req() request) {
Logger.log(req.user.email);
}
You can make this more convenient by creating a custom decorator:
import { createParamDecorator } from '#nestjs/common';
export const User = createParamDecorator((data, req) => {
return req.user;
});
and then inject #User instead of #Req.

Resources