Two API call in single sesrvices - api

First I'm new new to angular 2. I'm trying to call two difference API in single service. But it wont return any value second API 'getCityById' but the API 'getCities' return the value.
Here my code:
import { Injectable } from '#angular/core';
import { Http, Headers,Response} from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
import { Cities } from './cities';
#Injectable()
export class CitiesService {
private CityListUrl = "APIurl";
private CityUrl = "APIurl2";
constructor(private http: Http) {}
getCities(): Observable<Cities[]> {
const headers = new Headers();
headers.append('Access-Control-Allow-Headers', 'Content-Type');
headers.append('Access-Control-Allow-Methods', 'GET,PUT,POST,OPTIONS');
headers.append('Access-Control-Allow-Origin', '*');
return this.http.get(this.CityListUrl,{headers: headers})
.map(this.extractData)
.catch(this.handleError);
}
getCityById(CityId:Number): Observable<any> {
const headers = new Headers();
headers.append('Access-Control-Allow-Headers', 'Content-Type');
headers.append('Access-Control-Allow-Methods', 'GET,PUT,POST,OPTIONS');
headers.append('Access-Control-Allow-Origin', '*');
var params = 'cityid='+CityId;
console.log("____________"+this.CityUrl);
console.log(this.http.post(this.CityUrl,params,{headers: headers})
.map(this.extractData));
return this.http.post(this.CityUrl,params,{headers: headers})
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
console.log(res);
let Cities = res.json();
return Cities || { };
}
private handleError(error: Response) {
console.log(error);
return Observable.throw(error.json().error || "500 internal server error");
}
}
I'm not sure what I'm wrong. Please help with this.

Related

"Response is not defined" when using ngrx effects with HttpClient

I'm currently rewriting old request service to use HttpClient instead of Http. My app makes use of ngrx store and after I rewrote request service, it stopped working.
here's my request service:
import { Injectable } from '#angular/core';
import {HttpClient, HttpHeaders} from '#angular/common/http';
import { ToastController } from 'ionic-angular';
import { ReplaySubject } from 'rxjs/ReplaySubject';
import { Config } from '../app/app.config';
import {Observable} from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { Version } from '#angular/compiler';
export enum HttpStatus {
UNAUTHORIZED,
WRONGVERSION,
UNVERIFIED,
NONETWORK,
}
export interface HttpNotifierData {
status: HttpStatus
}
#Injectable()
export class HttpClientService {
private httpNotifier: ReplaySubject<HttpNotifierData>;
constructor(
public toastCtrl: ToastController,
private _http: HttpClient,
) {
this.httpNotifier = new ReplaySubject();
}
createHeaders(contentType?: string) {
var headers = new HttpHeaders();
let token = localStorage.getItem('auth_token');
let expires = localStorage.getItem('auth_expires');
let appVersion = Config.version+'';
if(token)
headers = headers.set( 'Authorization', 'Bearer ' + token);
if(expires)
headers = headers.set( 'TokenExpiration', expires);
if(appVersion)
headers = headers.set( 'App-Version', appVersion);
if(contentType === 'form')
headers = headers.set('Content-Type','application/x-www-form-urlencoded');
return headers;
}
createAppVersionHeader(headers: Headers) {
let appVersion = Config.version+'';
headers.append('App-Version', appVersion);
}
getHttpNotifier(): ReplaySubject<HttpNotifierData> {
return this.httpNotifier;
}
request(verb: string, url: string, data?: any, contentType?: string) {
let headers = this.createHeaders(contentType);
return this._http.request(verb, url, {
body: data,
headers: headers
}).catch(err => {
if (err.status == 0) {
this.httpNotifier.next({status: HttpStatus.NONETWORK});
err._body = 'Kunne ikke kontakte baksystem';
} else if (err.status == 401) {
this.httpNotifier.next({status: HttpStatus.UNAUTHORIZED});
} else if (err.status == 403) {
this.httpNotifier.next({status: HttpStatus.UNVERIFIED});
} else if (err.status == 412) {
this.httpNotifier.next({status: HttpStatus.WRONGVERSION});
} else {
// TODO: Convert API error to user friendly error
this.toastCtrl.create({
message: err._body,
duration: 3000,
showCloseButton: true,
closeButtonText: "Lukk",
cssClass: 'error',
}).present();
}
throw err;
});
}
get(url) {
let cache = '?cache=' + Math.ceil(Math.random() * 100000);
return this.request('GET', url + cache);
}
post(url, data, contentType = 'json') {
return this.request('POST', url, data, contentType);
}
put(url, data) {
return this.request('PUT', url, data);
}
delete(url) {
return this.request('DELETE', url);
}
}
my user auth service:
import { Injectable } from '#angular/core';
import { Config } from '../app/app.config';
import { HttpClientService } from "./http.service";
#Injectable()
export class UserService {
constructor(
private _http: HttpClientService
) { }
login(username: string, password: string) {
var data = "grant_type=password&username=" + username + "&password=" + password + "&deviceId=test";
return this._http.post(Config.apiUrl + 'Token', data, 'form');
}
getPin(phone: string) {
return this._http.post(Config.apiUrl + 'api/account/forgotPassword', {phoneNumber: phone})
}
}
my ngrx effect for authenticating user:
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/observable/of';
import { Injectable } from '#angular/core';
import { Effect, Actions } from '#ngrx/effects';
import { Observable } from 'rxjs/Observable';
import { UserService } from '../services/user.service';
import * as UserActions from '../actions/user.actions';
#Injectable()
export class UserEffects {
constructor(
private actions: Actions,
private userService: UserService
) {}
#Effect()
login:Observable<any> = this.actions
.ofType(UserActions.LOGIN)
.map((action: UserActions.Login) => action.payload)
.switchMap(payload => {
return this.userService.login(payload.username, payload.password)
.map((response:any) => new UserActions.LoginSuccess(JSON.parse(response._body)))
.catch((error) => Observable.of(new UserActions.LoginFailed(error._body)))
});
#Effect()
getPin:Observable<any> = this.actions
.ofType(UserActions.GET_PIN)
.map((action: UserActions.GetPin) => action.payload)
.switchMap(payload => {
return this.userService.getPin(payload)
.map((response: any) => new UserActions.GetPinSuccess())
.catch((error) => Observable.of(new UserActions.GetPinFailed(error._body)))
});
}
when debugging, I have this error appearing in effect module:
however, in network section I can see that request is completed successfully:
what can be wrong with my service?
ok, so I figured out the solution.
effects for login should have pipe and no json parsing:
#Effect()
login:Observable<any> = this.actions
.ofType(UserActions.LOGIN)
.map((action: UserActions.Login) => action.payload)
.switchMap(payload => {
return this.userService.login(payload.username, payload.password).pipe()
.map((response:any) => new UserActions.LoginSuccess(response))
.catch((error) => Observable.of(new UserActions.LoginFailed(error._body)))
});

How write header with nestjs

how I can write headers using way nest.js?
I'm currently using this:
import { Controller, Body, Get, Post, HttpCode, HttpStatus, Req, Res } from '#nestjs/common';
import { Request, Response } from 'express';
import { AuthService } from './auth.service';
import { Usuario } from '../usuario/usuario.entity';
import { JsonWebTokenError } from 'jsonwebtoken';
import { request } from 'http';
#Controller('auth')
export class AuthController {
constructor(private readonly authService: AuthService) { }
#Post('login')
#HttpCode(HttpStatus.OK)
async login(#Body('username') username: string, #Body('password') password: string, #Res() response: Response) {
this.authService
.validateUser(username, password)
.then((token) => {
response.setHeader('Authorization', 'Bearer ' + token);
let respuesta: any = {};
respuesta.success = true;
respuesta.token = token;
return response.send(respuesta);
});
}
}
I do not want to use response.setHeader('Authorization', 'Bearer ' + token); and return response.send(respuesta);
Thanks for your answers!
NestJS is build on top of express, so do it like in express:
async login(#Body('username') username: string, #Body('password') password: string, #Res() res: Response) {
const token = await this.authService.validateUser(username, password);
res.set('Authorization', 'Bearer ' + token);
res.send({
success: true,
token,
})
});
In latest versions you could use the #Header decorator within NestJS Core.
import { Controller, Get, Req, Header, Res } from '#nestjs/common';
import { Request, Response } from 'express';
#Controller('cookies')
export class CookiesController {
#Get('set')
// #Header('Set-Cookie', 'cookieName = 12345') // "Usin header decorator"
setCookie(#Res() response: Response): Response {
/*
* If using express approach, pass #Res as param decorator
*/
response.cookie('rememberme', '1') // Using express res object.
return response.send('Cookie has been set! :)')
}
#Get()
checkCookie(#Req() request: Request ): string {
console.log(Object.keys(request.cookies))
if(Object.keys(request.cookies).length > 0){
console.log('cookies =>', request.cookies)
return 'Cookies are set :)'
} else {
return 'Uh, oh! Cookie hasn\'t been set :\'('
}
}
}

Unable to send data in headers to authorize the request in php

I am getting the error message in cli like :
Type 'Headers' has no properties in common with type 'RequestOptionsArgs'
. However, the code executes. The version I am using is 5, as it shows in package.json. I am unable to find a good http example, which suit my need. I want to send some parameters in headers section, and authorize it in php. Here is the service code:
user.service.ts
import { Observable } from 'rxjs/Observable';
import { Customer } from './../models/customer';
import { Injectable } from "#angular/core";
import { Http, Response, Headers, RequestOptions } from "#angular/http";
import "rxjs/add/operator/map";
import { apiServicesURL,appServicesURL } from "../constants/globals";
import { HttpClient, HttpHeaders } from "#angular/common/http";
#Injectable()
export class UserService {
//headers : Headers ;
constructor(private http: Http) {
}
getCustomerInfoo(custId): Observable<Customer> {
//cust.push({token : localStorage.getItem('token')});
console.log(apiServicesURL + 'getCustomers');
let token = localStorage.getItem('token');
let api_token = localStorage.getItem('api_token');
let email = localStorage.getItem('email');
let headers = new Headers({ 'Content-Type': 'application/json' });
// let options: RequestOptions = new RequestOptions({ headers: headers });
return this.http.post(apiServicesURL + 'getCustomers', JSON.stringify({ customer_id: custId, token: api_token, email: email }), headers ).map((response: Response) => {
// login successful if there's a jwt token in the response
return <Customer>response.json();
});
}
}
Any help, appreciated!!!
If you are using angular 5 then try it this below code and write RequestOptionsProvider to module.ts file
import { Injectable } from '#angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HTTP_INTERCEPTORS } from '#angular/common/http';
import { AuthService } from '#app/core/services/auth.service';
import { Observable } from 'rxjs/Observable';
#Injectable()
export class DefaultRequestOptionsService implements HttpInterceptor {
constructor(private auth: AuthService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Get the auth header from the service.
// const authHeader = this.auth.getAuthorizationHeader();
// Clone the request to add the new header.
// const authReq = req.clone({headers: req.headers.set('Authorization', authHeader)});
const authReq = req.clone({ headers: req.headers.set('Content-Type', 'application/json') });
// Pass on the cloned request instead of the original request.
return next.handle(authReq);
}
}
export const RequestOptionsProvider = { provide: HTTP_INTERCEPTORS, useClass: DefaultRequestOptionsService, multi: true };

HttpClient issue in angular5

I am working with Angular 4 with HttpService, i am trying to migrate to HttpClientService.
but i am getting the error as below
ERROR in src/app/app.service.ts(19,102): error TS2559: Type 'Headers' has no properties in common with type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
please refer my app.service.ts also
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { Observable } from 'rxjs/Observable';
import { map, catchError } from 'rxjs/operators';
#Injectable()
export class AppService {
// tslint:disable-next-line:max-line-length
private token: any = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjYxMmMyMDEyNmI1ZTY1ZGE3NWE3YmQ3MmJlNGYzMDIzYWZ5a9';
public headers = new Headers({
'Content-type': 'application/json',
'Authorization' : `Bearer ${this.token}`
});
constructor(private http: HttpClient) { }
getData() {
return this.http.get('http://192.111.99.**/cloudnew/public/api/generic/registrations/view/0', this.headers);
}
}
Based on the comment below.... I would suggest implementing Http interceptors.... something like this....
You first need an authentication service that grabs the token at first, then you can store the token ad send it with each request with interceptors..
import { Inject, Injectable, Optional, OnInit, OnDestroy } from '#angular/core';
import { HttpClient, HttpHeaders, HttpResponse, HttpErrorResponse } from '#angular/common/http';
import { Observable, Subject, Subscription } from 'rxjs';
import * as moment from 'moment';
#Injectable()
export class AuthService implements OnInit, OnDestroy {
subscriptions: Subscription[] = [];
constructor(private http: HttpClient) {}
ngOnInit() {
this.subscriptions.push(this.login().subscribe(res=> this.handleLogin(res)));
}
ngOnDestroy() {
this.subscriptions.forEach(s=> s.unsubscribe());
}
getBaseHeader(): HttpHeaders {
const header = new HttpHeaders({
'Content-Type': 'application/json'
});
return header;
}
getAuthHeaders(): HttpHeaders {
const headers = new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': this.token
});
return headers;
}
getHeaders(): HttpHeaders {
if(this.token && this.validateToken()) {
return this.getAuthHeaders();
} else {
return this.getBaseHeader();
}
}
storeLogin(response: Response) {
.... store login token etc...
}
getStoredLogin(): any {
... get login/token etc...
}
getToken(): string {
return this.token;
}
login(): Observable<Response> {
const headers = new Headers({'Content-Type': 'application/json'});
const options = new RequestOptions({headers: headers});
return this.http.post(path, { body to be sent ie login password }, options);
}
loggedIn(): boolean {
return ....login crentials | false/null;
}
validateToken() {
return moment(this.tokenExpiration).isAfter(moment().second());
}
handleError(err: Response, fn?: string) {
console.log(typeof err);
if(fn) console.log(fn);
console.log(err.toString());
}
}
then the interceptor......
import { Injectable, Injector } from '#angular/core';
import { HttpEvent, HttpHandler, HttpRequest, HttpInterceptor } from '#angular/common/http';
import { Observable } from 'rxjs/Observable';
import { AuthService } from '../../services/auth.service';
#Injectable()
export class ApiInterceptor implements HttpInterceptor {
constructor(private inj: Injector) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let authService = this.inj.get(AuthService);
const authHeader = authService.getHeaders();
const authReq = req.clone({headers: authHeader});
return next.handle(authReq);
}
}
This way you the interceptors do all the work for you after the initil login. Simplified the code to more of a shell than a snippet of a working application

Angular 5.2 & RxJS 5.5 HttpInterceptor retryWhen, but update request?

I am trying to intercept a 401 response, send a refresh token request before trying request again (but with a different header). I have it working except retryWhen does not give me to modify the original request header. So I've been trying to use catchError instead but I cannot seem to execute the request again.
Here is my current retryWhen:
import {Injectable} from '#angular/core';
import {
HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpErrorResponse
}
from '#angular/common/http';
import {Observable} from 'rxjs/Observable';
import {CustomerService} from "../customer/customer.service";
import * as ApplicationSettings from "application-settings";
import {retryWhen, map} from "rxjs/operators";
import {LoginResponse} from "./LoginResponse";
/**
* This takes a request that requires an access_token and refreshes it on 401 errors.
*/
#Injectable()
export class RefreshTokenInterceptor implements HttpInterceptor {
public constructor(private customer: CustomerService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
retryWhen(errors => {
return Observable.create(observer => {
errors.forEach((error: HttpErrorResponse) => {
if (error.status === 401) {
let refresh_token = ApplicationSettings.getString('refresh_token');
return this.customer.refreshToken(refresh_token).subscribe(
(response: LoginResponse) => {
this.customer.setToken(response);
let headers = req.headers.set('Authorization', `Bearer ${response.access_token}`);
console.log(`Bearer ${response.access_token}`);
let newReq = req.clone({headers: headers});
observer.next(next.handle(newReq));
observer.complete();
},
error2 => {
observer.error();
}
);
} else {
observer.error();
}
});
});
})
);
}
}
If I swap out retryWhen with catchError:
catchError((err, caught) => {
console.log('err: ' + JSON.stringify(err));
if (err.status === 401) {
console.log('401 !!!! REFRESH MEH!');
let newReqOb: Observable<HttpEvent<any>> = Observable.create(observer => {
console.log('going to refresh token');
let refresh_token = ApplicationSettings.getString('refresh_token');
let refresh = this.customer.refreshToken(refresh_token);
refresh.subscribe((response: LoginResponse) => {
console.log('token refreshed!');
this.customer.setToken(response);
let access_token = ApplicationSettings.getString('access_token');
let headers = req.headers.set('Authorization', `Bearer ${access_token}`);
console.log(`Bearer ${access_token}`);
let newReq = req.clone({headers: headers});
observer.next(next.handle(newReq)); // <-- HERE IT WONT FIRE
observer.complete();
});
});
return newReqOb;
}
return caught;
})
The important part is I am returning next.handle(newReq) and it doesn't seem to fire the request. If I switch it to next.handle(newReq).subscribe(), the request will fire but no callbacks are triggered.
Here is the full example with retryWhen:
import {Inject, Injectable} from '#angular/core';
import {
HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpErrorResponse, HttpClient
}
from '#angular/common/http';
import {Observable, ObservableInput} from 'rxjs/Observable';
import {CustomerService} from "../customer/customer.service";
import * as ApplicationSettings from "application-settings";
import {retryWhen, map, catchError} from "rxjs/operators";
import {LoginResponse} from "./LoginResponse";
import {APP_CONFIG, AppConfig} from "../../app.config";
/**
* This takes a request that requires an access_token and refreshes it on 401 errors.
*/
#Injectable()
export class RefreshTokenInterceptor implements HttpInterceptor {
public constructor(private customer: CustomerService, private http: HttpClient, #Inject(APP_CONFIG) private config: AppConfig) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
catchError((err, caught) => {
console.log('err: ' + JSON.stringify(err));
if (err.status === 401) {
console.log('401 !!!! REFRESH MEH!');
let newReqOb: Observable<HttpEvent<any>> = Observable.create(observer => {
console.log('going to refresh token');
let refresh_token = ApplicationSettings.getString('refresh_token');
let refresh = this.customer.refreshToken(refresh_token);
refresh.subscribe((response: LoginResponse) => {
console.log('token refreshed!');
this.customer.setToken(response);
let access_token = ApplicationSettings.getString('access_token');
let headers = req.headers.set('Authorization', `Bearer ${access_token}`);
console.log(`Bearer ${access_token}`);
let newReq = req.clone({headers: headers});
observer.next(next.handle(newReq));
observer.complete();
});
});
return newReqOb;
}
return caught;
})
);
}
}
I did find out the issue, here is the resulting code:
import {Inject, Injectable} from '#angular/core';
import {
HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpErrorResponse, HttpClient
}
from '#angular/common/http';
import {Observable, ObservableInput} from 'rxjs/Observable';
import {CustomerService} from "../customer/customer.service";
import * as ApplicationSettings from "application-settings";
import {catchError, switchMap, finalize} from "rxjs/operators";
import {LoginResponse} from "./LoginResponse";
import {APP_CONFIG, AppConfig} from "../../app.config";
import {RouterExtensions} from "nativescript-angular/router";
/**
* This takes a request that requires an access_token and refreshes it on 401 errors.
* #TODO What happens on 400 errors?
*/
#Injectable()
export class RefreshTokenInterceptor implements HttpInterceptor {
isRefreshingToken: boolean = false;
public constructor(private customer: CustomerService,
private http: HttpClient,
private router: RouterExtensions,
#Inject(APP_CONFIG) private config: AppConfig) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let validate = {
is_api_v1: req.url.indexOf('api/v1') > -1,
is_not_register_end_point: !(req.url.indexOf('api/v1/customers') > -1 && req.method === 'POST')
};
if (validate.is_api_v1 && validate.is_not_register_end_point) {
return next.handle(req).pipe(
catchError((err, caught) => {
if (err instanceof HttpErrorResponse && err.status === 401) {
console.log(req.url);
console.log('Injecting Refresh Token');
return this.handle401Error(req, next);
}
// return caught;
})
);
} else {
return next.handle(req);
}
}
handle401Error(req: HttpRequest<any>, next: HttpHandler) {
//-- Test if we are refreshing so we are not stuck in an infinite loop
if (!this.isRefreshingToken) {
this.isRefreshingToken = true;
let refresh_token = ApplicationSettings.getString('refresh_token');
let refresh = this.customer.refreshToken(refresh_token);
return refresh.pipe(
switchMap((tokenResp: LoginResponse) => {
this.customer.setToken(tokenResp);
let access_token = ApplicationSettings.getString('access_token');
let headers = req.headers.set('Authorization', `Bearer ${access_token}`);
return next.handle(req.clone({headers: headers}));
}),
catchError(error => {
ApplicationSettings.setBoolean("authenticated", false);
this.router.navigate(["/login"], { clearHistory: true, queryParams: {
error: 'Your session is no longer valid, please log in again',
}});
return Observable.throw("");
}),
finalize(() => {
this.isRefreshingToken = false;
})
)
}
}
}