In the earlier angular version, in our service, we could simply map the response to a JSON object as follow :
import { Injectable } from '#angular/core';
import 'rxjs/add/operator/map';
import { HttpClient } from '#angular/common/http';
#Injectable()
export class MakeService {
constructor(private http:HttpClient) { }
getMakes(){
return this.http.get('/api/myAPI')
.map(res=>res.json());
}
}
However, in angular 5 we don't have HTTP anymore and we have to use HttpClient instead, what should be added to the code above to work in angular5.
my component looks like :
makes : any[];
constructor(private makeservice: MakeService) { }
ngOnInit() {
this.makeservice.getMakes().subscribe(makes=>{
this.makes=makes;
console.log("MAKES",this.makes);
});
}
simply by removing the ":any[]" data type from make it will work, but I need to pass the JSON object to component from service.
Try the following,
getMakes(){
return this.http.get('/api/myAPI')
}
and in component,
constructor(public data:DMakeService ){
this.data.getMakes().subscribe(data=>{
console.log(data);
})
}
You don't need to map to JSON anymore, so this is sufficient:
getMakes(){
return this.http.get('/api/myAPI');
}
This returns an Observable, however, not a Promise, so you'd have to subscribe the return value to get the result. If you want to keep working with promises, you can do this:
getMakes(){
return this.http.get('/api/myAPI').toPromise();
}
According here. You should always subscribe to any request made by httpclient
Always subscribe!
An HttpClient method does not begin its HTTP request until you call
subscribe() on the observable returned by that method. This is true
for all HttpClient methods.
const req = http.get<Heroes>('/api/heroes');
// 0 requests made - .subscribe() not called.
req.subscribe();
// 1 request made.
req.subscribe();
// 2 requests made.
Related
I have searched about it in google, Yes I understood that am receiving context/type:text/html not application/json,but I didn't get how to solve this issue. when I trying to hit the api of third party user from my local server , am getting this error. Please check the screenshot of this error.
service.ts
export class VamosysService {
constructor(private _http:Http){}
getVechicalLocations():Observable<any[]>{
return this._http.get(API_URL)
.pipe(map((response:Response)=<any[]>response.json()));
}
component.ts
export class VamosysComponent implements OnInit {
vechicalLocation:any[];
constructor(private _vamoService:VamosysService) { }
ngOnInit() {
this._vamoService.getVechicalLocations()
.subscribe((data) => this.vechicalLocation = data);
}
}
Thanks in advance
You are using HttpModule which is deprecated you should use HttpClientModule instead
In new HttpClientModule JSON is an assumed default and no longer needs to be explicitly parsed using res.json()
Service
import { HttpClient } from '#angular/common/http';
export class VamosysService {
constructor(private _httpc:HttpClient){}
getVechicalLocations():Observable<any[]>{
return this._httpc.get(API_URL);}
Component
export class VamosysComponent implements OnInit {
public vechicalLocation=[];
constructor(private _vamoService:VamosysService) { }
ngOnInit() {
this._vamoService.getVechicalLocations()
.subscribe((data) => this.vechicalLocation=data);
}}
In Case if you are Requesting non-JSON data
you can use the responseType property.
getVechicalLocations():Observable<any[]>{
return this._httpc.get(API_URL,{ responseType: 'text' });}
response type could be responseType?: 'arraybuffer' | 'blob' | 'json' | 'text'
I had a similar error when getting a string back from the response. My error was:
error: {error: SyntaxError: Unexpected token W in JSON at position 0 at JSON.parse () at XMLHttp…, text: "We've just sent you an email to reset your password."}
And I don't have control over the actual response. However, I found this in the documentation which specifically sets that you can be expecting non-JSON responses. So you would have something like
return this._http.get(API_URL, {responseType: 'text'}) // Notice the additional parameter here
.pipe(map((response:Response)=<any[]>response.json()));
I notice you're also specifically parsing json after though, so it would be depending on the actual response on how you want to handle it.
According to your STACKBLITZ. The api that you have used is not working properly. If it changed to working get api call it is working properly. WORKING demo with different test api call.
and instead of using Http I'm suggesting you to use HttpClient with additional benefits.
The HttpClient in #angular/common/http offers a simplified client HTTP
API for Angular applications that rests on the XMLHttpRequest
interface exposed by browsers. Additional benefits of HttpClient
include testability features, typed request and response objects,
request and response interception, Observable apis, and streamlined
error handling.
Then you no need explicitly parsed into json inside map. And also it will return a observable type. You could just consume the return json after subscribe to it.
Before you can use the HttpClient, you need to import the Angular HttpClientModule (into root AppModule).
Sample AppModule code:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { HttpClientModule } from '#angular/common/http';
#NgModule({
imports: [
BrowserModule,
// import HttpClientModule after BrowserModule.
HttpClientModule,
],
declarations: [
AppComponent,
],
bootstrap: [ AppComponent ]
})
export class AppModule {}
Then import HttpClient inside your VamosysService
import { HttpClient } from '#angular/common/http';
Try to use getVechicalLocations() like below
constructor(private _http: HttpClient) { }
getVechicalLocations(){
return this._http.get(API_URL);
}
Hope this helps to you!
Trying to follow an online video, then this appears, I am new to angular, other solutions are not helping me out.
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
import 'rxjs/add/operator/map';
/*
Generated class for the WeatherProvider provider.
See https://angular.io/guide/dependency-injection for more info on providers
and Angular DI.
*/
#Injectable()
export class WeatherProvider {
apikey='7d2dc7a226a78c14';
url;
constructor(public http: HttpClient) {
console.log('Hello WeatherProvider Provider');
this.url='http://api.wunderground.com/api/'+this.apikey+'/conditions/q'
}
getWeather(city,state){
return this.http.get(this.url+'/'+state+'/'+city+'.json')
.map(res => res.json() );
}
}
If you're using the new HttpClient you don't need to parse JSON because it's decoded automatically for you:
https://angular.io/guide/http#type-checking-the-response
The HttpClient.get() method parsed the JSON server response into the anonymous Object type. It doesn't know what the shape of that object is.
Also https://angular.io/guide/http#requesting-non-json-data.
With angular 5 and httpClient, you don't need to use the map part anymore.
Read more here: https://angular.io/guide/http#type-checking-the-response
getWeather(city,state){
return this.http.get(this.url+'/'+state+'/'+city+'.json');
}
If you want to get data in specific format, You can tell HttpClient the type of the response to make consuming the output easier and more obvious.
export interface Config {
heroesUrl: string;
textfile: string;
}
And then :
getConfig() {
// now returns an Observable of Config
return this.http.get<Config>(this.configUrl);
}
Found some answers for angularjs like: How to use angular.toJson on a angular controller or scope but not Angular 2 and following.
I'm new to Angular, worked through the tutorial, and now trying to build my first live app. I have a credentials object that has fields username and password. I want to externalize this to JSON to send to my web service. I found this: https://angular.io/api/common/JsonPipe which seems to do what I want, but the example is in HTML and I want to do it in my service, so here's my service:
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { JsonPipe } from '#angular/common';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
#Injectable()
export class LoginService {
authToken = ""
loginUrl = "localhost:8093/login"
constructor(private http: HttpClient) { }
login(credentials): Observable<String> {
var url = this.loginUrl
+ '?payload='
+ (credentials | json)
return of(url);
}
}
But I get an error on the line + (credentials | json) saying json is not found, maybe I meant JSON?
Did I?
Just use
JSON.stringify(credentials)
like in plain JavaScript.
The | json pipe is only for view binding like
{{credentials | json}}
but not for TypeScript code.
import { Injectable } from '#angular/core';
import { Http,Response } from '#angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
#Injectable()
export class CommentService{
private _url :string ="https://jsonplaceholder.typicode.com/posts"
constructor(private _http:Http){}
// method to fetch CommentS from a api service
getComments(){
return this._http.get(this._url)
.map((response:Response)=> response.json())
.catch(this._errorHandler);
}
_errorHandler(error:Response){
console.error(error);
return Observable.throw(error ||"Server Error");
}
}
the above code works great with this url https://jsonplaceholder.typicode.com/posts
but does not work with this url http://ergast.com/api/f1/2016/driverStandings.json
any ideas ...TIA
Aravind is on the right track here, but MRData case sensitive, and mapping is a bit off. The correct way to map the response here would be:
return this._http.get(this._url)
.map((response:Response)=> response.json().MRData)
.catch(this._errorHandler);
}
Your component:
getData() {
this.service.getData()
.subscribe(data => {
this.data = data;
});
}
Then you can access data, e.g like:
<div>
<b>Series:</b> {{data?.series}}<br>
<a><b>Url:</b> {{data?.url}}</a>
</div>
Then you seem to have a lot of nested objects in your response, so this might help you: Access / process (nested) objects, arrays or JSON
Here's a demo with mock JSON, but I did try that url you provided and the data was received fine. So replicating the plunker should work fine in your app :)
DEMO
To make the second one work you need to get the data using
return this._http.get(this._url)
.map((response:Response)=> response.MRDATA.json())
.catch(this._errorHandler);
}
Because in this working one the data is in array of objects type Meaning
The one which does not work is completely single object
I'm having a tough time understanding how to access different aspects of an JSON object in Angular2. Particularly, I have a web API that I built that returns the following JSON object regarding the hard drive details on my server:
The image is a screenshot of my console in Chrome after using an httpService and Observable to push it to the console but understanding how to get to a specific piece of info is getting lost on me.
If someone could point me in the right direction, it would be greatly appreciated.
After having subscribed to the http Observable you have already got the actual object.
Assuming your http get request looks like this:
this.httpService.get(this.apiUrl);
you can use the power of rxjs Observables, for example map over the object like this:
this.httpService.get(this.apiUrl)
.map(res => res.json())
.map(body => body.Data)
.map(data => data[0].AvailableSpace)
which after subscribing to would return the AvailableSpace.
.subscribe(availablespace => console.log(availablespace);
Watch out for accessing arrays like this, this is just to give you an example on how to access and manipulate objects in observables.
Check this site out for more information on different observable
operators, other than map.
https://www.learnrxjs.io/
Let me try my luck. Hope it will help people understand better. Particularly, I will talk about how to perform get request in Angular 2. It is always better to have a get and post request in a separate file called service.ts as mentioned in the official documentation.
We will have three files, namely example.component.ts, example.service.ts and Model file examplemodel.ts
example.component.ts
import {OnInit, Component} from "#angular/core";
import {ExampleService} from "./example.service"; // import service
import {ResponseFromGet, ErrorMessage} from "./examplemodel"; // import your model
#Component({
providers: [ExampleService], // add your service here in order to use in component file
templateUrl: './example.template.html'
})
export class ExampleComponent implements OnInit{
//Specify Url for Get request
Private _getRequestUrl = "http://entergetrequesturlhere";
// Make variable for stroing get method reponse which can be used in ur template file
responseFromGetMethod: ResponseFromGet; // this can be ur model file which represnts ur JSON model
// For storing Error
errorMessage: ErrorMessage;
//use Constructor to inject your service in component file
constructor(private _exampleService: ExampleService){}
// Since we implemented OnInit we need to override its method ngOnInit
// this method is called when page is loaded
ngOnInit(): any{
this.callGetMethod(this._getRequestUrl);
}
// callGetMethod outside OnInit but inside class ExampleComponent
callGetMethod(getUrl: string){
this._exampleService.getMethodName(getUrl)
.subscribe(
responseFromGetMethod => {
this.responseFromGetMethod = responseFromGetMethod; // Store response from getmethod in your local variable
},
error => this.errorMessage = <any>error // Store error message receiver from server
);
}
}
example.service.ts
import {Http, Response} from "#angular/http";
import {Injectable} from "#angular/core";
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import {ResponseFromGet} from "./examplemodel";
#Injectable()
export class ExampleService{
constructor(private _http: Http) { }
// GET request To access data and specify observable type from model
getMethodName(getUrl): Observable<ResponseFromGet>{
return this._http.get(getUrl)
.map(this.extractData) // to check for the status code
.catch(this.handleError); // to check error
}
// Extracts from response
private extractData(res: Response) {
if (res.status < 200 || res.status >= 300) {
throw new Error('Bad response status: ' + res.status);
}
let response = res.json();
return response || {};
}
// To handle Error
private handleError(error: Response) {
console.error(error);
return Observable.throw(error.json() || 'Server error');
}
}
examplemodel.ts
export interface ResponseFromGet{
id: number;
name: string;
}
export interface ErrorMessage{
message: string;
}
And finally the HTML file
example.template.html
<div>
<h2>{{responseFromGetMethod?.name}}</h2> // this will print the name from the json file
<h3>{{errorMessage?.message}}</h3> // this will print the error if any
</div>
Lastly, this is the model of my JSON file
{
"id": 789;
"name": "Angular2";
}