Angular2 appear warning XMLHttpRequest at chrome - rest

I used Http Restful API at Angular2, but appear the following warning message.
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
Please tell me how to do that.
http_restful_service.ts
import { Injectable } from '#angular/core';
import { Http, Headers, Response } from '#angular/http';
import { Observable } from 'rxjs/Observable';
#Injectable()
export class HTTPRestfulService {
constructor(private _http: Http) {}
getAllProjectName() {
var headers = new Headers();
headers.append('Content-Type','charset=uft-8');
return
this._http.get('http://localhost/api/database/',
{headers: headers})
.map(res => res.json());
}
}
backstage_view.component.ts
import { Component, OnInit } from '#angular/core';
import { HTTPRestfulService } from './../../../service/http_restful_service';
#Component({
moduleId: module.id,
selector: 'backstage_view',
templateUrl: './backstage_view.component.html',
styleUrls: ['./backstage_view.component.css']
})
export class BackstageViewComponent implements OnInit {
allProjects: string;
constructor(private _restfulapi: HTTPRestfulService) {}
ngOnInit() {
this._restfulapi.getAllProjectName()
.subscribe(
data => this.allProjects = data,
error => console.log(error),
);
}
}

Why can't you pass the content-type as 'application/json' format,
let url= `http://localhost/api/database/`;
let headers = new Headers();
headers.append('Content-Type','application/json');
let params = new URLSearchParams;
params.append('id', id);
params.append('user_id', user_id);
return this.authHttp.post( url, { headers:headers, search:params })
.map(res => res.json());

Related

API calls from one angular service is not being intercepted by jwt -interceptor - while all others are ok

In my angular-ionic app I have several services calling REST apis in the backend.
All API calls are intercepted by jwt-interceptor and bearer token is being added except 1 .
The funny thing is that one method (getVehicles) is begin intercepted correctly while the concerned method (createVehicle) is not being intercepted. Any ideas?
Pls find code for my service
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { Observable } from 'rxjs';
import { VehicleModel } from '../models/vehicle.model';
import { environment } from 'src/environments/environment';
import { Criteria } from 'src/app/common/model/criteria.model';
#Injectable({
providedIn: 'root'
})
export class VehicleService {
constructor(private httpClient: HttpClient) { }
criteria: Criteria;
vehicle: VehicleModel;
baseUrl = environment.API_URL + '/api/vehicles';
vehicleRegistrationNumber: string;
// List of vehicles
public getVehicles(criteria: Criteria): Observable<VehicleModel[]> {
return this.httpClient.post<VehicleModel[]>(this.baseUrl + '/search', criteria);
}
// Create a new item
public createVehicle(vehicle: VehicleModel): Observable<VehicleModel> {
return this.httpClient.post<VehicleModel>(this.baseUrl + '/createVehicle', vehicle);
}
// Edit vehicle details
public updateVehicle(vehicle: VehicleModel): Observable<any> {
return this.httpClient.put<VehicleModel>(
this.baseUrl + '/updateVehicle', vehicle);
}
}
and code for jwt-inteceptor:
import { Injectable } from '#angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '#angular/common/http';
import { Observable } from 'rxjs';
import { AuthenticationService } from '#/_shared/_services';
#Injectable({ providedIn: 'root' })
export class JwtInterceptor implements HttpInterceptor {
constructor(private authenticationService: AuthenticationService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// add authorization header with jwt token if available
const currentUser = this.authenticationService.currentUserValue;
if (currentUser && currentUser.token) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${currentUser.token}`
}
});
}
return next.handle(request);
}
}

Ionic 3 + HttpClientModule and token from storage

I have build an interceptor for making HTTP requests to a PHP backend.
This backend gives an JWT token to the app and I save this in the Ionic Storage.
But I want to get that token from Storage and add it as an header to the HTTP request.
Below is my interceptor with and hardcoded token.
This works and I get a response from the backend.
See update # bottom of this post
http-interceptor.ts
import { HttpInterceptor, HttpRequest } from '#angular/common/http/';
import {HttpEvent, HttpHandler} from '#angular/common/http';
import { AuthProvider } from "../providers/auth/auth";
import {Injectable} from "#angular/core";
import {Observable} from "rxjs/Observable";
import {Storage} from "#ionic/storage";
#Injectable()
export class TokenInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const changedReq = req.clone({headers: req.headers.set('Authorization', 'Bearer MY TOKEN')});
return next.handle(changedReq);
}
}
But how do I get the token from storage into the header.
I searched alot and most of the tutorials / examples are from the older HTTP module. If someone has an idea or has a up2date example ?
UPDATE
Oke below code send the token
intercept(req: HttpRequest<any>, next: HttpHandler) : Observable<HttpEvent<any>>{
return fromPromise(this.Auth.getToken())
.switchMap(token => {
const changedReq = req.clone({headers: req.headers.set('Authorization', 'Bearer ' + token )});
return next.handle(changedReq);
});
}
With 1 exception, namely the first time I access that page :)
You can save JWT token in, for example, localStorage
localStorage.setItem('myToken', res.token);
and then access it with
localStorage.getItem('myToken');
In your case something like this:
import { HttpInterceptor, HttpRequest } from '#angular/common/http/';
import {HttpEvent, HttpHandler} from '#angular/common/http';
import { AuthProvider } from "../providers/auth/auth";
import {Injectable} from "#angular/core";
import {Observable} from "rxjs/Observable";
import {Storage} from "#ionic/storage";
#Injectable()
export class TokenInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const changedReq = req.clone({headers: req.headers.set('Authorization', localStorage.getItem('myToken'))});
return next.handle(changedReq);
}
}
If you want to use Ionic Storage
import { HttpInterceptor, HttpRequest } from '#angular/common/http/';
import {HttpEvent, HttpHandler} from '#angular/common/http';
import { AuthProvider } from "../providers/auth/auth";
import {Injectable} from "#angular/core";
import {Observable} from "rxjs/Observable";
import {Storage} from "#ionic/storage";
#Injectable()
export class TokenInterceptor implements HttpInterceptor {
constructor(public _storage: Storage) {
_storage.get('myToken').then((val) => {
console.log('Your age is', val);
});
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const changedReq = req.clone({headers: req.headers.set('Authorization', this.val)});
return next.handle(changedReq);
}
}
Caching the token in the interceptor is a bad idea because if the token changes the interceptor will not be aware of those changes.
// Don't do this.
token: string;
constructor(private storage: Storage) {
this.storage.get('token').then((res) => {
this.token = res;
})
}
If you want to use Ionic Storage and the interceptor together you can do so by using Observable.flatMap like so...
app.module.ts
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true},
SecurityStorageService
]
AuthInterceptor.ts
#Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(
private securityStorageService: SecurityStorageService
) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// This method gets a little tricky because the security token is behind a
// promise (which we convert to an observable). So we need to concat the
// observables.
// 1. Get the token then use .map to return a request with the token populated in the header.
// 2. Use .flatMap to concat the tokenObservable and next (httpHandler)
// 3. .do will execute when the request returns
const tokenObservable = this.securityStorageService.getSecurityTokenAsObservable().map(token => {
return request = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
});
return tokenObservable.flatMap((req) => {
return next.handle(req).do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
// do stuff to the response here
}
}, (err: any) => {
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
// not authorized error .. do something
}
}
});
})
}
security-storage-service.ts
You technically don't need this service, but you shouldn't have Ionic Storage logic in your interceptor.
#Injectable()
export class SecurityStorageService {
constructor(private storage: Storage) {
}
getSecurityToken() {
return this.storage.get(StorageKeys.SecurityToken)
.then(
data => { return data },
error => console.error(error)
);
}
getSecurityTokenAsObservable() {
return Observable.fromPromise(this.getSecurityToken());
}
}
storage-keys.ts
export class StorageKeys {
public static readonly SecurityToken: string = "SecurityToken";
}
For anyone who comes across this like me and is using rxjs >=5.5.0 then you can just do:
auth-interceptor.ts
#Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private authService: AuthService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return from(this.authService.getToken()).pipe(mergeMap((token) => {
const changedReq = req.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
return next.handle(changedReq);
}));
}
auth-service.ts
public async getToken() {
return await this.storage.get('ACCESS_TOKEN');
}

Angular2: strange vague error when trying to get Json from server using a rest service

I am trying to get a product from a local server using an angular2 rest service. When I do the GET I get the following error. I can get the item from the server using the Insomnia rest client so I know the issue is not with the server. i've also checked the url and made sure there's no errors there. Any idea what else I can check? i'm using ng-cli to run the app...
my error:
http://10.60.160.34/BRMServices/WebEnquiry//POSEnquiry/293
Failed to load resource: net::ERR_CONNECTION_RESET
app.component.ts:32
failureServer error
my rest service:
import { Injectable } from '#angular/core';
import { Http, Headers, Response, RequestOptions } from "#angular/http";
import { Observable } from "rxjs/Rx";
import { ProductModel } from "../models/product.model";
//import 'rxjs/add/operator/map';
//import 'rxjs/add/operator/catch';
//import 'rxjs/add/observable/throw'
#Injectable()
export class RestService {
public API_URL: string = "http://10.60.160.34/BRMServices/WebEnquiry/";
private headers: Headers;
private options: RequestOptions;
constructor(private http: Http){
this.init();
}
init() {
this.headers = new Headers({ 'Content-Type': 'application/json' });
this.options = new RequestOptions({ headers: this.headers });
}
getProduct(barcode: string): Observable<ProductModel> {
return this.http.get(this.API_URL + "/POSEnquiry/" + barcode, this.options)
.map((res: Response) => res.json())
.catch((error: any) => Observable.throw(error.json().error || 'Server error'));
}
}
my app.component.ts:
import { Component } from '#angular/core';
import { RestService } from "./services/rest.service";
import { ProductModel } from "./models/product.model";
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
product: ProductModel;
constructor(private restService: RestService){}
submitBarcode(barcode: HTMLInputElement){
this.restService.getProduct(barcode.value)
.subscribe((res) => {
//product = res;
console.log(res);
}, (res) => {
console.log("failure" + res);
});
//console.log("product: " + product);
}
}
It turned out to be the RequestOptions variable. When I replaced options with headers in the get request it worked with no issues...

Angular2 REST API

I learn Angular2 and now i try to get my data from a rest service. My rest service works and i can get data from there.
But angular always give my this error message: JSON.parse: unexpected character at line 1 column 1 of the JSON data
This is my Service:
import { Injectable } from '#angular/core';
import { Http, Response, Headers, RequestOptions } from '#angular/http';
import { Person } from '../_models/person';
import { Observable } from 'rxjs/Observable';
#Injectable()
export class PersonService {
private headers: Headers;
constructor(private http: Http)
{
this.headers = new Headers();
this.headers.append('Content-Type', 'application/json');
this.headers.append('Accept', 'application/json');
}
getPersons(): Observable<Person[]> {
return this.http.get('http://localhost:54612/api/Person')
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body.data || {};
}
private handleError(error: Response | any) {
// In a real world app, we might use a remote logging infrastructure
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
}
This is the component for the view:
import { Component, OnInit } from '#angular/core';
import { Person } from '../_models/person';
import { PersonService } from '../_services/person.service';
#Component({
moduleId: module.id,
templateUrl: 'login.component.html',
providers: [ PersonService ]
})
export class LoginComponent implements OnInit {
errorMessage: string;
personen: Person[] = [];
constructor(private personService: PersonService) { }
ngOnInit() { this.getPersons(); }
getPersons() {
this.personService.getPersons()
.subscribe(
personen => this.personen = personen,
error => this.errorMessage = <any>error);
}
}
And this is my view:
<h1>Tour of Heroes</h1>
<h3>Heroes:</h3>
<ul>
<li *ngFor="let person of personen">{{person.IDPerson}}</li>
</ul>
<p class="error" *ngIf="errorMessage">{{errorMessage}}</p>
Your server is return XML. The reason is probably because it's the default when you don't explicitly set the Accept to something else. You have set it in the Headers to JSON, but you never add the headers to the request. You need to do
this.http.get('http://localhost:54612/api/Person', { headers: this.headers });
Try this snippet, in your getPersons()
return this.http.get('http://localhost:54612/api/Person',{headers: this.headers })
.map((response:Response) => response.json())

angular 2 consume REST api

I have the heroes app from angular tutorial and i am trying to make it consume REST API. API is build in DRF. I removed the in memory providers from app.module.ts and added HTTP_PROVIDERS. Here is the app.module.ts file now.
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { HttpModule, HTTP_PROVIDERS } from '#angular/http';
import { AppComponent } from './app.component';
import { routing } from './app.routing';
import { HeroesComponent } from './heroes.component';
import { DashboardComponent } from './dashboard.component';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroService } from './hero.service';
import { HeroSearchComponent } from './hero-search.component';
#NgModule({
imports: [
BrowserModule,
FormsModule,
routing,
HttpModule
],
declarations: [
AppComponent,
HeroesComponent,
DashboardComponent,
HeroDetailComponent,
HeroSearchComponent,
],
providers: [
HeroService,
HTTP_PROVIDERS,
],
bootstrap: [ AppComponent ]
})
export class AppModule {
}
In hero.service.ts i changed just the url.
import { Injectable } from '#angular/core'
import { Http, Headers, Response } from "#angular/http";
import 'rxjs/add/operator/toPromise'
import { Hero } from './hero'
#Injectable()
export class HeroService{
private heroesUrl = 'http://127.0.0.1/api/heroes/heroes/'; // URL to web api
constructor(private http: Http){}
private handleError(error: any): Promise<any> {
console.error('An error occurred', error);
return Promise.reject(error.message || error);
}
private post(hero: Hero): Promise<Hero> {
let headers = new Headers({
'Content-Type': 'application/json'
});
return this.http
.post(this.heroesUrl, JSON.stringify(hero), {headers: headers})
.toPromise()
.then(res => res.json().data)
.catch(this.handleError)
}
private put(hero: Hero): Promise<Hero> {
let headers = new Headers();
headers.append('Content-Type', 'application.json');
let url = `${this.heroesUrl}/${hero.id}`;
return this.http
.put(url, JSON.stringify(hero), {headers: headers})
.toPromise()
.then(() => hero)
.catch(this.handleError)
}
delete(hero: Hero): Promise<Response> {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
let url = `${this.heroesUrl}/${hero.id}`;
return this.http
.delete(url, {headers: headers})
.toPromise()
.catch(this.handleError)
}
save(hero: Hero): Promise<Hero> {
if (hero.id) {
return this.put(hero);
} else {
return this.post(hero);
}
}
getHeroes(): Promise<Hero[]> {
return this.http.get(this.heroesUrl)
.toPromise()
.then(response => response.json().data as Hero[])
.catch(this.handleError);
}
getHero(id: number): Promise<Hero> {
return this.getHeroes().then(heroes => heroes.find(hero => hero.id === id))
}
}
As far as i can tell from google chrome developer tools i got the answer from django with no problem what so ever but its not showing on the page.
No errors in console also.
Headers from api request:
Request URL:http://127.0.0.1/api/heroes/heroes/
Request Method:GET
Status Code:200 OK
Remote Address:127.0.0.1:80
Allow:GET, POST, HEAD, OPTIONS
Connection:keep-alive
Content-Type:application/json
Date:Mon, 22 Aug 2016 11:01:39 GMT
Server:nginx/1.4.6 (Ubuntu)
Transfer-Encoding:chunked
Vary:Accept, Cookie
X-Frame-Options:SAMEORIGIN
Response:
[{"name":"noname","id":1},{"name":"noname3","id":2},{"name":"noname3","id":3},{"name":"noname2","id":4},{"name":"noname2","id":5},{"name":"noname2","id":6}]
Do not know if it is important or not but here are my nginx conf
server {
listen 80;
server_name team_up.org;
charset utf-8;
root /opt/team_up/team_up-web-client/;
index index.html;
location / {
try_files $uri$args $uri$args/ $uri/ /index.html =404;
}
}
remove HTTP_PROVIDERS from declarations. HTTP_PROVIDERS are deprecated and aren't needed when importing HttpModule.