Ionic 2 Waiting for multiple responses - javascript

I'm having some problems with my app login page. I'm new with Ionic 2 and Angular and I have tried to figure this out with help of Google but no success so far...
These lines here are causing the problem, alert is returning "undefined" as soon as I click login button, even thought it should wait for response.
let accessToken = this.getAccessToken();
let details = this.getProfileDetails(accessToken);
alert(JSON.stringify(details));
Whole code:
import { Component } from '#angular/core';
import { NavController, Platform } from 'ionic-angular';
import { FbProvider } from '../../providers/fb-provider';
import { TabsPage } from '../tabs/tabs';
import { Http } from '#angular/http';
import 'rxjs/add/operator/map';
#Component({
selector: 'page-login',
templateUrl: 'login.html'
})
export class LoginPage {
platform
fb
email
name
id
constructor(public navCtrl: NavController, pf: Platform, fbProvider: FbProvider, public http: Http) {
this.platform = pf;
this.fb = fbProvider;
this.email = '';
this.name = '';
this.id = '';
}
ionViewDidLoad() {
console.log('Hello LoginPage Page');
}
fbLogin() {
let accessToken = this.getAccessToken();
let details = this.getProfileDetails(accessToken);
alert(JSON.stringify(details));
}
getAccessToken(){
this.fb.login().then((fbLoginData) => {
let params = new FormData();
params.append('facebookAccessToken', fbLoginData.authResponse.accessToken);
this.http.post('http://myHostUrl/api/accessToken', params).map(res => res.json())
.subscribe(
data => {
return data.accessToken;
},err => {
alert(err);
}
);
},(err) => {
alert('Facebook login failed');
});
}
getProfileDetails(accessToken){
let params = new FormData();
params.append('accessToken', accessToken);
this.http.post('http://myHostUrl/api/userDetails', params).map(res => res.json())
.subscribe(
data => {
return data;
},err => {
alert(err);
}
);
}
}

It's undefined because you need to wait the asynchronous functions to finish. The following code it's done with rxjs to manage the asynchrony of the two functions and the http calls. try it.
fbLogin() {
this.getAccessToken()
.switchMap(accessToken => this.getProfileDetails(accessToken))
.first() // Just one and complete ....
.subscribe(
details => alert(JSON.stringify(details)),
error => alert(error)
);
}
getAccessToken() : Observable<any> {
return Observable.fromPromise(<Promise<any>> this.fb.login())
.map(fbLoginData => fbLoginData.authResponse.accessToken)
.switchMap(accessToken => {
let params = new FormData();
params.append('facebookAccessToken', accessToken);
return this.http.post('http://myHostUrl/api/accessToken', params)
.map(res => res.json())
.map(data => data.accessToken)
});
}
getProfileDetails(accessToken) : Observable<any>{
let params = new FormData();
params.append('accessToken', accessToken);
return this.http.post('http://myHostUrl/api/userDetails', params).map(res => res.json());
}

Related

Why does my angular Interceptor take old value of token from localstorage?

When I login API sends to me the token and token-life-time , when token-life-time is going to be end , I refresh my token by sending request to API and receive new token and new refresh-token-time.
When I refresh or navigate to another page (at the moment when token-life-time is over) my interceptor sends old value of token from LocalStorage and API gives me an error 'Not correct token' when I again refresh or navigate to another page it sends correct token.
But it repeats when the token-life-time is going to be over as described above.
Here is my token-interceptor.service.ts
import { Injectable } from '#angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpHeaders } from '#angular/common/http';
import { Observable } from 'rxjs';
import { LoginService } from '../services/login.service';
#Injectable()
export class TokenInterceptorService implements HttpInterceptor {
constructor(
private loginService: LoginService
) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (
this.loginService.isLogged
) {
const token = localStorage.getItem('access-token');
const headers = new HttpHeaders().set('Authorization', `Bearer ${token}`);
request = request.clone({ headers: headers });
}
return next.handle(request);
}
}
It takes token and send request to API.
I have the login.service.ts with login and refresh function .Login function put token value into the LocalStorage and Refresh function refreshes the token in LocalStorage if isNeedToRefresh var is true and it works well.
refresh(): Observable<boolean> {
return this.http.post(`${environment.auth}/refresh`, {
token_hash: localStorage.getItem('refresh-token')
}).pipe(
map((res: any) => {
if (res.access && res.refresh) {
localStorage.setItem('access-token', res.access.hash);
localStorage.setItem('expires-at-access', res.access.expires_at);
localStorage.setItem('refresh-token', res.refresh.hash);
localStorage.setItem('expires-at-refresh', res.refresh.expires_at);
return true;
} else {
this.notificationService.error(res && res.result_descr || '');
return false;
}
}),
catchError(() => of(false))
);
}
Here is where I refresh the token in login.component.ts
ngOnInit() {
if (this.loginService.isLogged) {
if (this.loginService.isNeedToRefresh === true) {
this.loginService.refresh().subscribe((res: boolean) => {
if (res === true) {
this.router.navigate(['']);
}
});
} else if (this.loginService.isNeedToRefresh === false) {
this.router.navigate(['']);
}
}
}
Also I update my token in app.component.ts
ngOnInit() {
$(document).on('click', '[href="#"]', e => e.preventDefault());
this.router.events.subscribe((val) => {
if (val instanceof NavigationEnd) {
if (!(val.url.indexOf('/login') === 0)) {
this.authWatcher();
}
}
});
}
authWatcher() {
if (this.loginService.isLogged) {
if (this.loginService.isNeedToRefresh === true) {
this.loginService.refresh().subscribe((refresh: boolean) => {
if (refresh === false) {
this.authModalRef = this.modalService.show(this.staticModal, { backdrop: 'static' });
} else {
this.loginService.checkToken().subscribe((check: boolean) => {
if (!check) {
this.logoutService.logout();
this.router.navigate(['login']);
}
});
}
});
}
}
What's the best way for my interceptor to work well ?
Little update , here is how I check isNeedToRefresh
get isNeedToRefresh(): boolean {
const accessExpireTimestamp = new Date(
localStorage.getItem('expires-at-access')
).getTime();
const refreshExpireTimestamp = new Date(
localStorage.getItem('expires-at-refresh')
).getTime();
const nowTimestamp = new Date().getTime();
if (nowTimestamp >= accessExpireTimestamp) {
if (nowTimestamp >= refreshExpireTimestamp) {
return null; // Refresh token expired
} else {
return true; // Refresh token not expired
}
}
return false;
}
This desicion is worked for me , if someone else would meet such issue
I have fully re-writed my interceptor , basing on this link
import { Injectable } from '#angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '#angular/common/http';
import { LoginService } from '../services/login.service';
import { Observable, BehaviorSubject, Subject } from 'rxjs';
import { switchMap, take, filter } from 'rxjs/operators';
#Injectable()
export class TokenInterceptorService implements HttpInterceptor {
private refreshTokenInProgress = false;
private refreshTokenSubject: Subject<any> = new BehaviorSubject<any>(null);
constructor(public loginService: LoginService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (request.url.indexOf('refresh') !== -1) {
return next.handle(request);
}
const accessExpired = this.loginService.accessExpired;
const refreshExpired = this.loginService.refreshExpired;
if (accessExpired && refreshExpired) {
return next.handle(request);
}
if (accessExpired && !refreshExpired) {
if (!this.refreshTokenInProgress) {
this.refreshTokenInProgress = true;
this.refreshTokenSubject.next(null);
return this.loginService.refresh().pipe(
switchMap((authResponse) => {
console.log('authResponse ', authResponse)
if (authResponse) {
const token = localStorage.getItem('access-token');
this.refreshTokenInProgress = false;
this.refreshTokenSubject.next(token);
return next.handle(this.injectToken(request));
} else {
return next.handle(request);
}
}),
);
} else {
return this.refreshTokenSubject.pipe(
filter(result => result !== null),
take(1),
switchMap((res) => {
return next.handle(this.injectToken(request))
})
);
}
}
if (!accessExpired) {
return next.handle(this.injectToken(request));
}
}
injectToken(request: HttpRequest<any>) {
const token = localStorage.getItem('access-token');
return request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
}
}

Ionic 4 + HttpInterceptor + token

I'm trying to authenticate all the API calls to the backend using an HttpInterceptor in an Ionic 4 project. The token is saved through NativeStorage. The problem occurs when I make the login call. Since there is not yet an available token, NativeStorage returns an error interrupting the chain: NativeStorageError {code: 2, source: "Native", exception: null}
httpConfig.interceptor.ts
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpResponse,
HttpErrorResponse
} from '#angular/common/http';
import { Observable, throwError, from } from 'rxjs';
import { map, catchError, switchMap } from 'rxjs/operators';
import { Injectable } from '#angular/core';
import { LoadingController } from '#ionic/angular';
import { NativeStorage } from '#ionic-native/native-storage/ngx';
const TOKEN_KEY = 'auth-token';
#Injectable()
export class HttpConfigInterceptor implements HttpInterceptor {
loaderToShow: any;
loadingPresent = false;
debug = false;
constructor(
public loadingController: LoadingController,
private storage: NativeStorage
)
{ }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return from(this.storage.getItem(TOKEN_KEY))
.pipe(
switchMap(token => {
if (token) {
request = request.clone({ headers: request.headers.set('Authorization', 'Bearer ' + token.access_token) });
}
if (!request.headers.has('Content-Type')) {
request = request.clone({ headers: request.headers.set('Content-Type', 'application/json') });
}
this.showLoader();
return next.handle(request).pipe(
map((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
console.log('event--->>>', event);
}
this.hideLoader();
return event;
}),
catchError((error: HttpErrorResponse) => {
this.hideLoader();
return throwError(error);
})
);
})
);
}
showLoader() {
console.log("show loader");
this.loaderToShow = this.loadingController.create({
message: 'Cargando datos...'
}).then((res) => {
this.loadingPresent = true;
res.present();
res.onDidDismiss().then((dis) => {
console.log('Loading dismissed!');
});
});
}
hideLoader() {
if(this.loadingPresent) {
this.loadingController.dismiss();
this.loadingPresent = false;
}
}
}
auth.service.ts
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { Platform } from '#ionic/angular';
import { tap, map } from 'rxjs/operators';
import { NativeStorage } from '#ionic-native/native-storage/ngx';
import { environment } from '../../environments/environment';
import { User } from '../models/user';
import { BehaviorSubject } from 'rxjs';
const TOKEN_KEY = 'auth-token';
#Injectable({
providedIn: 'root'
})
export class AuthService {
isLoggedIn = false;
token:any;
authenticationState = new BehaviorSubject(false);
constructor(
private http: HttpClient,
private storage: NativeStorage,
private plt: Platform
)
{
this.plt.ready().then(() => {
this.checkToken();
});
}
login(login: String, password: String) {
return this.http.post(environment.API_URL + 'auth/login',
{ login: login, password: password }
).pipe(
map(token => {
this.storage.setItem(TOKEN_KEY, token)
.then(
() => {
this.authenticationState.next(true);
},
error => console.error('Error storing item', error)
);
}),
);
}
logout() {
return this.http.get(environment.API_URL + 'auth/logout')
.pipe(
tap(data => {
return this.storage.remove(TOKEN_KEY).then(() => {
this.authenticationState.next(false);
});
})
)
}
isAuthenticated() {
return this.authenticationState.value;
}
checkToken() {
this.storage.getItem(TOKEN_KEY).then(res => {
if (res) {
this.authenticationState.next(true);
}
});
}
}
When I try to login the first time, it returns the "token not found" error by NativeStorage from the interceptor
NativeStorageError {code: 2, source: "Native", exception: null}
you try to access to 'TOKEN_KEY' item when item doesn't exist.
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return from(this.storage.getItem(TOKEN_KEY)) <-- //This causes error
or
checkToken() {
this.storage.getItem(TOKEN_KEY).then(res => { <-- //This causes error
if (res) {
this.authenticationState.next(true);
}
});
}
you must initialize default value for 'TOKEN_KEY' or add if else condition for controlling(checking) token
you can use this.storage.keys list for find your key
other error codes:
NATIVE_WRITE_FAILED = 1
ITEM_NOT_FOUND = 2
NULL_REFERENCE = 3
UNDEFINED_TYPE = 4
JSON_ERROR = 5
WRONG_PARAMETER = 6
the get function from ionic storage return the value as object { value : "token value "}
so access value property from storage result like this
request = request.clone({ headers: request.headers.set('Authorization', 'Bearer ' +
token.value) });

View is rendered before user type is loaded from firestore

So I'm building an Ionic - Angular app that have an hospital patient submit a request to the nurse stuff and the nurse stuff can see their assigned requests (based on the room that assigned to the patient submitting the request). A nurse can see all requests and a patient can see only his/her requests. I have a function in the auth.service.ts that is called (setUserType() ) once a user is logged in manually or if it is an auto login(token is stored and found) and fetch the user type and name once it finished authentication.
The problem is, in the my-requests.page.ts in NgOnInit I call a function in the requests service that run a query to fetch all requests(if it is a nurse) or to fetch only the user's requests(if it is a patient) based on the user type I assigned once login/auto login occured. This field is unassigned once the my-requests.page.html is rendered and I can't seem to find a way to make it render only after I have the user type information.
setUserType() function:
let userId: string;
this.userIdObservable.subscribe(x => {
userId = x;
});
const userQuery = this.firestore.doc<Users>(`added-users/${userId}`);
userQuery.valueChanges().subscribe(x => {
this._userType = x.type;
this._userName = x.name;
});
My requests ngOnInit function:
ngOnInit() {
this.segment.value = 'progress';
this.requestSubscription = this.requestsService
.loadRequests()
.subscribe(requests => {
this.requestsList = requests;
});
}
Now all the auth functions -
Auth page Authenticate function:
authenticate(email: string, password: string) {
this.isLoading = true;
this.loadingCtrl
.create({
keyboardClose: true,
message: 'Logging in...'
})
.then(loadingEl => {
loadingEl.present();
let authObs: Observable<AuthResponseData>;
if (this.isLogin) {
authObs = this.authService.login(email, password);
} else {
authObs = this.authService.signup(email, password);
}
authObs.subscribe(resData => {
console.log(resData);
this.isLoading = false;
loadingEl.dismiss();
this.authService.setUserType();
this.router.navigateByUrl('/requests/tabs/add-requests');
}, errRes => {
loadingEl.dismiss();
const code = errRes.error.error.message;
let message = 'Could not sign you up, please try again.';
if (code === 'EMAIL_EXISTS') {
message = 'This Id exists already!';
} else if (code === 'EMAIL_NOT_FOUND') {
message = 'No such user.';
} else if (code === 'INVALID_PASSWORD') {
message = 'Could not log you in, please try again.';
}
this.showAlert(message);
});
});
}
Auth service login function:
login(email: string, password: string) {
return this.http
.post<AuthResponseData>(
`https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=${
environment.firebaseAPIKey
}`,
{ email: email, password: password, returnSecureToken: true }
)
.pipe(tap(this.setUserData.bind(this)));
}
Auth service autologin function:
autoLogin() {
return from(Plugins.Storage.get({ key: 'authData' })).pipe(
map(storedData => {
if (!storedData || !storedData.value) {
return null;
}
const parsedData = JSON.parse(storedData.value) as {
token: string;
tokenExpirationDate: string;
userId: string;
email: string;
};
const expirationTime = new Date(parsedData.tokenExpirationDate);
if (expirationTime <= new Date()) {
return null;
}
const user = new User(
parsedData.userId,
parsedData.email,
parsedData.token,
expirationTime
);
return user;
}),
tap(user => {
if (user) {
this._user.next(user);
this.setUserType();
}
}),
map(user => {
return !!user;
})
);
}
This is how you can do you dont have to include it in any module cli will do that for you.
import {Component, Injectable, OnInit} from '#angular/core';
import {BehaviorSubject} from 'rxjs';
import {FormGroup} from '#angular/forms';
#Injectable({
providedIn: 'root'
})
export class UserStateService {
private user = new BehaviorSubject({
isLoggedIn: false,
userType: null
});
constructor() {
}
setUser(user) {
this.user.next(user);
}
getUser() {
return this.user;
}
}
// my request
#Component({
selector: 'request-component',
templateUrl: './request-component.html'
})
export class RequestComponent implements OnInit {
constructor(private userStateService: UserStateService) {}
ngOnInit(): void {
this.userStateService
.getUser()
.subscribe(
((val: {isLoggedIn: boolean, userType: any}) => {
// calll you service
}));
}
}
// in your auto login or login you call setter
this.userStateService.setUser({isLoggedIn: true, userType: 'data from login'});

Cannot Dismiss LoadingController In Error Response Of Subscribe() - Ionic 4

I'm displaying a LoadingController when the user tries to login. Meanwhile, an API is being called.
I’m able to dismiss the LoadingController when I get a SUCCESS response from subscribe, but when I get an ERROR response, I’m not able to dismiss. Please help!
I’m a professional Python developer and a total newbie to Ionic, just started a day ago. So, please assist as such.
import { Component, OnInit } from '#angular/core';
import { ToastController, LoadingController } from '#ionic/angular';
import { CallapiService } from '../callapi.service';
#Component({
selector: 'app-login',
templateUrl: './login.page.html',
styleUrls: ['./login.page.scss'],
})
export class LoginPage implements OnInit {
userEmail = '';
userPassword = '';
loginUrl = 'login/';
loginMethod = 'POST';
postBody = {};
constructor(
public toastController: ToastController,
public loadingController: LoadingController,
private callApiService: CallapiService,
) { }
ngOnInit() {
}
async presentToast(displayMessage) {
const toast = await this.toastController.create({
message: displayMessage,
duration: 2000,
position: 'middle',
});
return await toast.present();
}
async presentLoading(loadingMessage) {
const loading = await this.loadingController.create({
message: loadingMessage,
});
return await loading.present();
}
loginUser() {
if (this.userEmail === '' || this.userPassword === '') {
this.presentToast('Email and password are required.');
}
else {
this.presentLoading('Processing...');
this.postBody = {
email: this.userEmail,
password: this.userPassword,
};
this.callApiService.callApi(this.loginUrl, this.postBody, this.loginMethod).subscribe(
(success) => {
console.log(success);
this.loadingController.dismiss();
},
(error) => {
console.log(error);
this.loadingController.dismiss();
}
);
this.loadingController.dismiss();
}
}
}
Without any service,
Same issue I faced while using Ionic 4 loading controller.
After trial and error I got working solution.
As loading controller functions are using async and await because both are asynchronous functions.
dismiss() function will called before present() function because, dismiss function will not wait until creating and presenting the loader, it will fire before present() as soon function will call.
Below is working code,
loading:HTMLIonLoadingElement;
constructor(public loadingController: LoadingController){}
presentLoading() {
if (this.loading) {
this.loading.dismiss();
}
return new Promise((resolve)=>{
resolve(this.loadingController.create({
message: 'Please wait...'
}));
})
}
async dismissLoading(): Promise<void> {
if (this.loading) {
this.loading.dismiss();
}
}
someFunction(){
this.presentLoading().then((loadRes:any)=>{
this.loading = loadRes
this.loading.present()
someTask(api call).then((res:any)=>{
this.dismissLoading();
})
})
}
this.callApiService.callApi(this.loginUrl, this.postBody, this.loginMethod)
.subscribe(
(data) => {
// Called when success
},
(error) => {
// Called when error
},
() => {
// Called when operation is complete (both success and error)
this.loadingController.dismiss();
});
Source: https://stackoverflow.com/a/54115530/5442966
Use Angular property binding. Create a component to your loading:
import { Component, Input } from '#angular/core';
import { LoadingController } from '#ionic/angular';
#Component({
selector: 'app-loading',
template: ''
})
export class LoadingComponent {
private loadingSpinner: HTMLIonLoadingElement;
#Input()
set show(show: boolean) {
if (show) {
this.loadingController.create().then(loadingElem => {
this.loadingSpinner = loadingElem;
this.loadingSpinner.present();
});
} else {
if (this.loadingSpinner) {
this.loadingSpinner.dismiss();
}
}
}
constructor(private loadingController: LoadingController) {}
}
...then in 'login.page.html' use your componente:
...
<app-loading [show]="showLoading"></app-loading>
... in 'LoginPage' create a property 'showLoading' and set it to true or false where you whant:
//.... some source code
export class LoginPage implements OnInit {
showLoading;
userEmail = '';
userPassword = '';
loginUrl = 'login/';
loginMethod = 'POST';
postBody = {};
//.... some source code
loginUser() {
if (this.userEmail === '' || this.userPassword === '') {
this.presentToast('Email and password are required.');
} else {
this.showLoading = true;
this.postBody = {
email: this.userEmail,
password: this.userPassword
};
this.callApiService
.callApi(this.loginUrl, this.postBody, this.loginMethod)
.subscribe(
success => {
console.log(success);
this.showLoading = false;
},
error => {
console.log(error);
this.showLoading = false;
}
);
this.showLoading = false;
}
}
}
This works for me, I reuse the loading component on others pages!
Recommended reading: https://angular.io/start
I actually ran into this exact issue and for me the answer was just to use await.
The functions for both creating and dismissing loaders return promises. What I realized was happening is that the subscribe/promise rejection was halting all other promises from completing. Now, I just await both presenting and dismissing and I have no issue:
async getData() {
//await presenting
await this.presentLoading('Loading...');
try {
let response = await this.httpService.getData();
await this.loadingController.dismiss();
//...
catch(err) {
this.loadingController.dismiss();
//handle error
//...
}
}
async presentLoading(msg: string) {
const loading = await this.loadingController.create({
spinner: 'crescent',
message: msg
});
await loading.present();
}
I hope this simple solution helps!

How do I load data from an API into an array in Angular 2?

So last week I started learning AngularJS, only to realize that I'm better off learning Angular 2 instead. After much reading and tinkering with sample apps on Plunker, I'm finally ready to dive into Angular 2. Last week with AngularJS I was able to create a simple app that retrieves data from an API and turns that into a navigation menu. So this week I am attempting to port that code to Angular 2.
I can't say that it was easy, but after much fiddling I found that the reason it was not working was that it was not even pulling the data. Below is my code for the service that pulls the data.
./src/app/navigation.service.ts
import { NavItem } from './navigation.model';
import { Injectable } from '#angular/core';
import { Http, Headers } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class NavService {
sections: NavItem[] = [];
categories: NavItem[] = [];
constructor(private http: Http) {
}
loadSections() {
//var headers = new Headers();
//headers.append('Content-Type', 'application/json');
this.http
.get('http://localhost:15557/api/navigation/sections/list')
.map(res => {
return res.json()
})
.subscribe(
data => {
this.sections = data;
},
err => this.logError(err),
() => console.log("Loaded all sections")
);
}
loadCategories(id) {
this.http
.get('http://localhost:15557/api/navigation/categories/' + id)
.map(res => res.json())
.subscribe(
data => this.categories = [data],
err => this.logError(err),
() => console.log("Loaded categories in section with id " + id)
);
}
logError(err) {
console.error('There was an error: ' + err);
}
}
./src/app/navigation.model.ts
export class NavItem {
// I am never going to use int unless I need to do math operations //
id: string;
name: string;
pid: string;
slug: string;
constructor(id: string, name: string, pid: string, slug: string) {
this.id = id;
this.name = name;
this.pid = pid;
this.slug = slug;
}
}
./src/app/navigation.component.ts
import { Component } from '#angular/core';
import { NavItem } from './navigation.model';
import { NavService } from './navigation.service';
#Component({
selector: 'app-navigation',
templateUrl: './navigation.component.html',
styleUrls: ['./navigation.component.css']
})
export class NavComponent {
public section: NavItem;
constructor(private service: NavService) { }
ngOnInit() {
this.service.loadSections();
}
}
What am I doing wrong with this code?
I have never used a service like that before. Maybe your implematation has a simple error, but here is how I always implement a service in angular. :)
Service
getSomething() {
return this.http.get('your-api-url').map(res => {
return res.json()
});
}
Component
makeRequest() {
this.service.getSomething().subscribe(data => {
this.variable = data;
}, err => {
console.log("error :/");
});
}

Categories