Property 'json' does not exist on type 'Object'
For future visitors: In the new HttpClient
(Angular 4.3+), the response
object is JSON by default, so you don't need to do response.json().data
anymore. Just use response
directly.
Example (modified from the official documentation):
import { HttpClient } from '@angular/common/http';@Component(...)export class YourComponent implements OnInit { // Inject HttpClient into your component or service. constructor(private http: HttpClient) {} ngOnInit(): void { this.http.get('https://api.github.com/users') .subscribe(response => console.log(response)); }}
Don't forget to import it and include the module under imports in your project's app.module.ts:
...import { HttpClientModule } from '@angular/common/http';@NgModule({ imports: [ BrowserModule, // Include it under 'imports' in your application module after BrowserModule. HttpClientModule, ... ], ...
UPDATE: for rxjs > v5.5
As mentioned in some of the comments and other answers, by default the HttpClient deserializes the content of a response into an object. Some of its methods allow passing a generic type argument in order to duck-type the result. Thats why there is no json()
method anymore.
import {throwError} from 'rxjs';import {catchError, map} from 'rxjs/operators';export interface Order { // Properties}interface ResponseOrders { results: Order[];}@Injectable()export class FooService { ctor(private http: HttpClient){} fetch(startIndex: number, limit: number): Observable<Order[]> { let params = new HttpParams(); params = params.set('startIndex',startIndex.toString()).set('limit',limit.toString()); // base URL should not have ? in it at the en return this.http.get<ResponseOrders >(this.baseUrl,{ params }).pipe( map(res => res.results || []), catchError(error => _throwError(error.message || error)) );}
Notice that you could easily transform the returned Observable
to a Promise
by simply invoking toPromise()
.
ORIGINAL ANSWER:
In your case, you can
Assumming that your backend returns something like:
{results: [{},{}]}
in JSON format, where every {} is a serialized object, you would need the following:
// Somewhere in your src folderexport interface Order { // Properties}import { HttpClient, HttpParams } from '@angular/common/http';import { Observable } from 'rxjs/Observable';import 'rxjs/add/operator/catch';import 'rxjs/add/operator/map';import { Order } from 'somewhere_in_src'; @Injectable()export class FooService { ctor(private http: HttpClient){} fetch(startIndex: number, limit: number): Observable<Order[]> { let params = new HttpParams(); params = params.set('startIndex',startIndex.toString()).set('limit',limit.toString()); // base URL should not have ? in it at the en return this.http.get(this.baseUrl,{ params }) .map(res => res.results as Order[] || []); // in case that the property results in the res POJO doesnt exist (res.results returns null) then return empty array ([]) }}
I removed the catch section, as this could be archived through a HTTP interceptor. Check the docs. As example:
https://gist.github.com/jotatoledo/765c7f6d8a755613cafca97e83313b90
And to consume you just need to call it like:
// In some component for examplethis.fooService.fetch(...).subscribe(data => ...); // data is Order[]
The other way to tackle it is to use this code snippet:
JSON.parse(JSON.stringify(response)).data
This feels so wrong but it works