In new HttpClientModule JSON is an assumed default and no longer needs to be explicitly parsed using res.json()
You can tell HttpClient
the type of the response to make consuming the output easier and more obvious.
Type checking of response can be done by using the type parameter
Create an Interface
export interface Idata{
userId:number;
Id:number;
title:string;
body:string;
}
Http
returns an observable
and We can tell the HttpClient.get
to return response
as Idata type When we use http.get<Idata[]>(...)
then it returns the instance of Observable<Idata[]>
type.
In your service
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {Observable} from 'rxjs';
import {Idata} from './Idata'
@Injectable()
export class ShareService {
constructor(private httpc:HttpClient)
{
}
public getPosts():Observable<Idata[]>
{
return this.httpc.get<Idata[]>('https://jsonplaceholder.typicode.com/posts');
}
}
In your component subscribe
to Observable<Idata[]>
to get instance of Idata
public data:Array<Idata>=[];
constructor(public service:ShareService)
{
this.service.getPosts().subscribe(value => {
this.data=value;
});
}
An alternative is Using async
pipe
AsyncPipe
accepts as an argument an observable
or a promise
, calls subscribe
or attaches a then handler, then waits for the asynchronous result before passing it through to the caller.
public response:Observable<Idata[]>;
constructor(public service:ShareService)
{
this.response=this.service.getPosts();
}
HTML
<div *ngFor="let item of (response|async)">
{{item.body}}
</div>
LIVEDEMO
my question is, how can I do this or is it really recommended to call
subscribe on my component and not in the service?
It's Good Practice to Delegate complex component logic to services
From Angular Style Guide
Do limit logic in a component to only
that required for the view. All other logic should be delegated to
services.
Do move reusable logic to services and keep components simple and
focused on their intended purpose.
Why? Logic may be reused by multiple components when placed within a
service and exposed via a function.
Why? Logic in a service can more easily be isolated in a unit test,
while the calling logic in the component can be easily mocked.
Why? Removes dependencies and hides implementation details from the
component.
Why? Keeps the component slim, trim, and focused.
Subscribing in Component lets you share a single http
request with multiple observers
, if you don't do so you would be violating DRY Principle
P:S
To share a single http
request for multiple observers
, you need something like the share
operator.
import {Observable} from 'rxjs';
import {share} from 'rxjs/operators'
export class dataService {
public data$=Observable<Idata[]>
constructor(http:HttpClient)
{
this.data$=this.http.get<Idata[]>('https://jsonplaceholder.typicode.com/posts').pipe(share());
}
public getPosts():Observable<Idata[]>
{
return this.data$
}
}
This operator is a specialization of publish
which creates a
subscription when the number of observers goes from zero to one, then
shares that subscription with all subsequent observers until the
number of observers returns to zero, at which point the subscription
is disposed.