How can I have HttpClient return the data as a JSON Object?
Angular docs say that HttpClient should parse returned JSON data as an object. In my project, it only returns the data as a string.
If I use JSON.parse, I can turn the data into an object and get the data that way and it works. But from what I've seen in articles, that is not good practice. Also, most articles/tutorials only use interfaces.
I've created an interface and tried using it, but it doesn't work. I've read so many posts and articles, but they all say that HttpClient should return an object by default.
Here is the code from my service. The first function gets the user's coordinates, and the second function uses the coordinates to request data from the api.
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, pipe } from 'rxjs';
import { map } from 'rxjs/operators';
import { environment } from '../../../environments/environment';
import { Aqi } from './aqi';
@Injectable({
providedIn: 'root'
})
export class AqiService {
aqiUrlCoords = `${environment.apiUri}airvisual/geo/`;
constructor(private http: HttpClient) {}
getLocation(): Observable<any> {
return Observable.create(observer => {
if(window.navigator && window.navigator.geolocation) {
window.navigator.geolocation.getCurrentPosition(
(position) => {
observer.next(position);
observer.complete();
},
(error) => observer.error(error)
);
} else {
observer.error('Unsupported Browser');
}
});
}
getGeoLocationAqi(lat, long): Observable<any> {
return this.http.get<any>(this.aqiUrlCoords, { params: {
lat: lat,
long: long
}});
}
}
to get the getGeoLocationAqi() function to work, I have to use this...
getGeoLocationAqi(lat, long): Observable<any> {
return this.http.get<any>(this.aqiUrlCoords, { params: {
lat: lat,
long: long
}}).pipe(
map(res => {
return JSON.parse(res);
})
);
}
Here is the component that uses the service and data. typeof always prints string.
import { Component, OnInit } from '@angular/core';
import { AqiService } from '../services/aqi/aqi.service';
import { Aqi } from './aqi';
export class GeoComponent implements OnInit {
aqi: any;
errorMessage: string;
constructor(private aqiService: AqiService) {}
ngOnInit() {
this.getCurrentCoordinatesAqi();
}
getCurrentCoordinatesAqi() {
this.aqiService.getLocation().subscribe(pos => {
let lat = pos.coords.latitude.toString();
let long = pos.coords.longitude.toString();
this.aqiService.getGeoLocationAqi(lat, long).subscribe((res) => {
this.aqi = res;
console.log(res);
console.log(typeof res);
});
}, (err) => {
this.errorMessage = err;
});
}
}
Here is the interface I have made.
export interface Aqi {
status: string,
data: {
city: string,
state: string,
country: string,
location: {
type: string,
coordinates: [
number,
number
]
},
current: {
weather: {
ts: string,
hu: number,
ic: string,
pr: number,
tp: number,
wd: number,
ws: number
},
pollution: {
ts: string,
aqius: number,
mainus: string,
aqicn: number,
maincn: string
}
}
}
}
Here is what is returned from the api by using postman.
{
"status": "success",
"data": {
"city": "Hanoi",
"state": "Hanoi",
"country": "Vietnam",
"location": {
"type": "Point",
"coordinates": [
105.81881,
21.021938
]
},
"current": {
"weather": {
"ts": "2019-04-30T16:00:00.000Z",
"hu": 100,
"ic": "04n",
"pr": 1010,
"tp": 25,
"wd": 70,
"ws": 2.6
},
"pollution": {
"ts": "2019-04-30T15:00:00.000Z",
"aqius": 151,
"mainus": "p2",
"aqicn": 76,
"maincn": "p2"
}
}
}
}
I expect typeof to print object, but it always prints string unless I use JSON.parse(). When I use the interface, I still get the string. Any help is appreciated!