How to Consume Http Component Efficiently in a Service in Angular 2 Beta

How to Consume Http Component efficiently in a service in angular 2 beta?

It's possible with Angular 2 to implement services. They simply correspond to injectable classes as described below. In this case this class can be injected into other elements like components.

import {Injectable} from 'angular2/core';
import {Http, Headers} from 'angular2/http';
import 'rxjs/add/operator/map';

@Injectable()
export class CompanyService {
constructor(http:Http) {
this.http = http;
}
}

You can inject an Http object in it (using its constructor) at the condition you specified HTTP_PROVIDERS when bootstraping the main component of your application:

import {bootstrap} from 'angular2/platform/browser'
import {HTTP_PROVIDERS} from 'angular2/http';
import {AppComponent} from './app.component'

bootstrap(AppComponent, [
HTTP_PROVIDERS
]);

This service can be then injected into a component, as described below. Don't forget to specify it within the providers list of the component.

import { Component, View, Inject } from 'angular2/core';
import { CompanyService } from './company-service';

@Component({
selector: 'company-list',
providers: [ CompanyService ],
template: `
(...) `
})

export class CompanyList {
constructor(private service: CompanyService) {
this.service = service;
}
}

You can then implement a method leveraging the Http object in your service and return the Observable object corresponding to your request:

@Injectable()
export class CompanyService {
constructor(http:Http) {
this.http = http;
}

getCompanies() {
return this.http.get('https://angular2.apispark.net/v1/companies/')
.map(res => res.json());
}
}

The component can then call this getCompanies method and subscribe a callback on the Observable object to be notify when the response is there to update the state of the component (in the same way you did with promises in Angular1):

export class CompanyList implements OnInit {
public companies: Company[];

constructor(private service: CompanyService) {
this.service = service;
}

ngOnInit() {
this.service.getCompanies().subscribe(
data => this.companies = data);
}
}

Edit

As foxx suggested in his comment, the async pipe could be also used to implicitly subscribe on the observable object. Here is the way to use it. First update your component to put the observable object in the attribute you want to display:

export class CompanyList implements OnInit {
public companies: Company[];

constructor(private service: CompanyService) {
this.service = service;
}

ngOnInit() {
this.companies = this.service.getCompanies();
}
}

Use then the async pipe in your template:

@Component({
selector: 'company-list',
providers: [ CompanyService ],
template: `
<ul>
<li *ngFor="#company of companies | async">{{company.name}}</li>
</ul>
`
})
export class CompanyList implements OnInit {
(...)
}

This article in two parts could give more details as well:

  • http://restlet.com/blog/2015/12/30/implementing-an-angular-2-frontend-over-an-apispark-hosted-web-api-part-1/
  • http://restlet.com/blog/2016/01/06/implementing-an-angular-2-frontend-over-an-apispark-hosted-web-api-part-2/

Hope it helps you,
Thierry

Calling web API from a service in Angular 2

You can use the following within your mobileService.ts file:

import 'Rxjs/add/operator/map'

This import should be done where you use the map method.

The following answers could help you as well:

  • Angular 2 HTTP GET with TypeScript error http.get(...).map is not a function in [null]
  • How to Consume Http Component efficiently in a service in angular 2 beta?

Hope it helps you,
Thierry

Angular 2 HTTP GET Equivalent to Angular HTTP GET

You can simply return an observable object (what the http.get method returns) from your your service, i.e. a class with the Injectable annotation:

@Injectable()
export class CompanyService {
constructor(http:Http) {
this.http = http;
}

getRandomQuote() {
return this.http.get('http://localhost:3001/api/random-quote')
.map(res => res.json());
}
}

Within your component, you can then inject this service and call the method that actually executes the HTTP request. To get the result, just use the subscribe method:

export class CompanyList implements OnInit {
public companies: Company[];

constructor(private service: CompanyService) {
this.service = service;
}

logError(err) {
}

ngOnInit() {
this.service.getRandomQuote().subscribe(
data => this.randomQuote = data,
err => this.logError(err),
() => console.log('Random Quote Complete')
);
}
}

You could have more details at this address: How to Consume Http Component efficiently in a service in angular 2 beta?.

Hope it will help you,
Thierry

how to get data from service in angular 2?

You could try this:

import {SharedService} from './service';

@Component({
(...)
providers: [SharedService]
})
export class MyComponent {
constructor(private service:SharedService) {
this.service.getData();
}
}

That said, I see strange things into your service since the Angular2 HTTP support leverages observables (asynchronous processing). I would refactor it this way:

@Injectable()
export class SharedService {
//sharingData: myData=[{name:"nyks"}];
constructor(private http:Http) {
}

getData:Array() {
return this.http.get('data.json')
.map(res => res.json());
}
}

and in the component:

import {SharedService} from './service';

@Component({
(...)
template: `
<ul>
<li *ngFor="d of dataToDisplay">{{d.name}}</li>
<ul>
`,
providers: [SharedService]
})
export class MyComponent {
constructor(private service:SharedService) {
this.service.getData().subscribe(data => {
this.dataToDisplay = data;
});
}
}

This answer could give you more details:

  • How to Consume Http Component efficiently in a service in angular 2 beta?

how to call http call in angular 2?

First you need to inject an Http instance into you component:

export class AppComponent {
toDoModel;

constructor(private _router:Router,private http:Http) {
this.http.get('data.json')
.map(res => res.json())
}
}

There are then two ways to display your data in an ngFor:

  • By subscribing on the observable returned by the get method

    @Component({
    template: `
    <ul>
    <li *ngFor="#elt of elements">{{elt.name}}</li>
    </ul>
    `
    })
    export class AppComponent {
    toDoModel;

    constructor(private _router:Router,private http:Http) {
    this.http.get('data.json')
    .map(res => res.json())
    .subscribe(data => {
    this.elements = data;
    });
    }
    }
  • By leveraging the async pipe

    @Component({
    template: `
    <ul>
    <li *ngFor="#elt of elements | async">{{elt.name}}</li>
    </ul>
    `
    })
    export class AppComponent {
    toDoModel;

    constructor(private _router:Router,private http:Http) {
    this.elements = this.http.get('data.json')
    .map(res => res.json());
    }
    }

Don't forget to specify HTTP_PROVIDERS when bootstrapping your application:

import {bootstrap} from 'angular2/platform/browser';
import {HTTP_PROVIDERS} from 'angular2/http';
import {AppComponent} from './app.component';

bootstrap(AppComponent, [ HTTP_PROVIDERS ]);

Here is the corresponding plunkr: https://plnkr.co/edit/bdFeiiAqrPDtFUdguw7s?p=preview.

You could also put your HTTP processing into a dedicated service as described below:

  • How to Consume Http Component efficiently in a service in angular 2 beta?

Using http rest apis with angular 2

Well good answer provided by @langley but I would like to add some more points so posting as an answer.

First of all for consuming Rest APIs we need the Http and HTTP_PROVIDERS modules to be imported. As we are talking about Http the very first step is obviously.

<script src="node_modules/angular2/bundles/http.dev.js"></script>

But yes it is a good practice to provide HTTP_PROVIDERS in the bootstrap file because by using this way it is provided on a global level and is available to the whole project like this.

bootstrap(App, [
HTTP_PROVIDERS, some_more_dependencies
]);

and the imports to be included are....

import {Http, Response, RequestOptions, Headers, Request, RequestMethod} from 'angular2/http';

Sometimes we need to provide Headers while consuming API's for sending access_token and many more things which is done this way:

this.headers = new Headers();
this.headers.append("Content-Type", 'application/json');
this.headers.append("Authorization", 'Bearer ' + localStorage.getItem('id_token'))

Now to RequestMethods: bascially we use GET, POST but there are some more options you can refer here...

We can use requestmethods as RequestMethod.method_name

There are some more options for the APIs but for now I have posted one example for POST request which will help you by using some important methods:

PostRequest(url,data) {
this.headers = new Headers();
this.headers.append("Content-Type", 'application/json');
this.headers.append("Authorization", 'Bearer ' + localStorage.getItem('id_token'))

this.requestoptions = new RequestOptions({
method: RequestMethod.Post,
url: url,
headers: this.headers,
body: JSON.stringify(data)
})

return this.http.request(new Request(this.requestoptions))
.map((res: Response) => {
if (res) {
return [{ status: res.status, json: res.json() }]
}
});
}

you can refer here too for more info.

see also -

  • How to deal with http status codes other than 200 in Angular 2.

Update

import has been changed from

import {Http, Response, RequestOptions, Headers, Request, RequestMethod} from 'angular2/http';

to

import {Http, Response, RequestOptions, Headers, Request, RequestMethod} from '@angular/http';

Angular2 post to web service

You need to subscribe() otherwise no request will be sent

send(subject, body)
{
var body = "subject=" + subject + "&body=" + body;

let result = this.http.post('http://172.16.2.115:3004/message',
body,
{
headers: this.headers
})
.subscribe(res => {
this.comments = res.json();
console.log(body);
console.log(this._apiUrl);

// no effect here
// return result;
});
}

You need to move the code that processes the repsonse into subscribe() otherwise it will be executed before the response arrived.
You can't return the result, you can only return the observable for someone else to subscribe.

send(subject, body)
{
var body = "subject=" + subject + "&body=" + body;

return this.http.post('http://172.16.2.115:3004/message',
body,
{
headers: this.headers
});
.map(res => {
this.comments = res.json();
});
}
this.send.subscribe(res => {
console.log(body);
console.log(this._apiUrl);
});

HTTP PROVIDERS in @Injectable Service

In fact observables are lazy. This means that corresponding HTTP requests aren't sent before attaching some response listeners on them using the subscribe method.

Adding a subscribe method in the constructor of your BrandsService should trigger your HTTP request:

import {Http} from 'angular2/http';
import {Injectable, Inject} from 'angular2/core';

@Injectable()
export class BrandsService{
constructor(public http: Http) {
console.log('Task Service created.', http);
http.get('http://google.fr').subscribe();
}
(...)
}

Hope it helps you,
Thierry

Angular2 @Input and http.get

There are two solutions for this:

You can use Elvis operator in your pagination.html

Page {{config?.total}}

This is from Angular documentation:

The Elvis operator (?) means that the employer field is optional and if undefined, the rest of the expression should be ignored.

Second solution would be to use Async Pipe:
https://angular.io/docs/ts/latest/api/common/AsyncPipe-class.html

In this case you would need to rewrite your code.



Related Topics



Leave a reply



Submit