I'm currently trying to teach myself Angular2 and TypeScript after happily working with Angular 1.* for the last 4 years! Anyway, I have a top level component that creates a property that is derived from a type I have created in another class. With my component when ngOnInit() is called I make a http call to a phoney REST service I wrote as a back end. Now when writing apps using AngularJS I would put my $http tasks into a service and inject them into my controllers... I would like to do the same with my component. Here's my component without the service code activated... notice the comments
import {Component, OnInit} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {Home} from './components/home/home';
import {UserStatus} from './types/types.ts'; // this is why my UserStatus Type is kept
import {UserData} from './services/user-data/UserData.ts'; // here is where I wish to write my sevice to perform the http tasks...
import {Http, Headers} from 'angular2/http';
@Component({
selector: 'app', // <app></app>
providers: [...FORM_PROVIDERS],
directives: [...ROUTER_DIRECTIVES],
pipes: [],
styles: [require('./app.scss')],
template: require('./app.html')
})
export class App {
userStatus: UserStatus;
constructor(public http: Http) {
this.userStatus = new UserStatus();
}
ngOnInit() {
// I really want to put this code into a seperate class and provide it as a service...
var headers = new Headers();
headers.append('Content-Type', 'application/json');
this.http.get('/restservice/userstatus', {headers: headers})
.map((data: any) => data.json())
.subscribe(
(data: any) => {
this.userStatus = data;
},
err => console.log(err), // error
() => console.log('getUserStatus Complete') // complete
);
/* I'd like to factor the above into a service kept in a diffent file like so*/
/*
UserData.getUserStatus().then((resp) => {
this.userStatus = resp;
})
*/
}
}
Now here is my type... for my userStatus property...
export class UserStatus {
constructor (
public firstName?: string,
public fullPersId?: number,
public goldUser?: boolean,
public hasProfileImage?: boolean,
public hideMoblieNavigationAndFooter?: boolean,
public persId?: string,
public profileName?: string,
public profilePicture?: string,
public showAds?: boolean,
public siteId?: number,
public url?: string,
public verified?: boolean,
public appOS?: any,
public formerName?: any
) {
this.firstName = firstName || '';
this.fullPersId = fullPersId || 0;
this.goldUser = goldUser || false;
this.hasProfileImage = hasProfileImage || false;
this.hideMoblieNavigationAndFooter = hideMoblieNavigationAndFooter || false;
this.persId = persId || '';
this.profileName = profileName || '';
this.profilePicture = profilePicture || '';
this.showAds = showAds || false;
this.siteId = siteId || 0;
this.url = url || '';
this.verified = verified || false;
this.appOS = appOS || null;
this.formerName = formerName || null;
}
}
Now I wish to put the http functionality of my Component into a serperate service... I started to write the following code (PLEASE DON'T LAUGH, I really am new to Angular2)
import {Injectable} from 'angular2/core';
import {Http, Headers} from 'angular2/http';
import {UserStatus} from '../../types/types.ts';
@Injectable()
export class UserData {
constructor(public http:Http) {
}
getUserStatus(): any {
var headers = new Headers();
headers.append('Content-Type', 'application/json');
this.http.get('/restservice/userstatus', {headers: headers})
.map((data: any) => data.json())
.subscribe(
(data: any) => {
return data;
},
err => console.log(err), // error
() => console.log('getUserStatus Complete') // complete
);
}
}
Now I was hoping I could call the service getUserStatus() method to perform the HTTP data fetch and call it in my App Component something like (I am using AngularJS 1.x promise example, but I know I should really use observables... I just don't know how!)
ngOnInit() {
UserData.getUserStatus().then((resp) => {
this.userStatus = resp;
});
}
This is obviously rubbish and I don't know what I am doing (examples/tutorials for Angular2 don't seem to be that great or practical so far). Can someone please show my how to wire the service then call it correctly in my Component?
I like this question because I went down the same road too and had to refactor my code. So best practice right now with RxJs observables is not to return the json in your .subscribe() method from the http request. Just map it and return it. What you are doing there is stripping it from all of the extra info it has.
You are supposed to return the observable which is the whole implementation of the get().
getUserStatus(): any {
var headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.get('/restservice/userstatus', {headers: headers})
.map((data: any) => data.json())
.catch(this.handleError)
);
}
private handleError(error: Response) {
// in a real world app, we may send the server to some remote logging infrastructure
// instead of just logging it to the console
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
Then on your component side you can simply subscribe to the observable
export class App {
public userStatus:any;
// Have to inject the UserData Service it into our component here.
constructor(public http: Http, private _userData: UserData ) {
}
ngOnInit() {
this._userData.getUserStatus()
.subscribe(
(status) => {
this.userStatus = status;
},
(err) => {
console.log(err);
},
()=>{console.log("User status complete")}
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With