I just have a question regarding structuring and handling responses from http requests within a service. I am using Angular2.alpha46 Typescript ( Just started testing it out- which I love... Ps.. Thank you all the people who have been working on it and contributing via github )
So take the following:
login-form.component.ts
import {Component, CORE_DIRECTIVES, FORM_DIRECTIVES} from 'angular2/angular2'; import {UserService} from '../../shared/service/user.service'; import {Router} from 'angular2/router'; import {User} from '../../model/user.model'; import {APP_ROUTES, Routes} from '../../core/route.config'; @Component({ selector: 'login-form', templateUrl: 'app/login/components/login-form.component.html', directives: [CORE_DIRECTIVES, FORM_DIRECTIVES] }) export class LoginFormComponent { user: User; submitted: Boolean = false; constructor(private userService:UserService, private router: Router) { this.user = new User(); } onLogin() { this.submitted = true; this.userService.login(this.user, () => this.router.navigate([Routes.home.as])) } }
from this component I import my userService which will house my http request to login the user the service looks like this:
user.service.ts
import {Inject} from 'angular2/angular2'; import {Http, HTTP_BINDINGS, Headers} from 'angular2/http'; import {ROUTER_BINDINGS} from 'angular2/router'; import {User} from '../../model/user.model'; export class UserService { private headers: Headers; constructor(@Inject(Http) private http:Http) { } login(user: User, done: Function) { var postData = "email=" + user.email + "&password=" + user.password; this.headers = new Headers(); this.headers.append('Content-Type', 'application/x-www-form-urlencoded'); this.http.post('/auth/local', postData, { headers: this.headers }) .map((res:any) => res.json()) .subscribe( data => this.saveJwt(data.id_token), err => this.logError(err), () => done() ); } saveJwt(jwt: string) { if(jwt) localStorage.setItem('id_token', jwt) } logError(err: any) { console.log(err); } }
What I want to do is to be able to handle the response the call returns after the http request. For instance if the user credentials are invalid I pass a 401 response back from the backend. My question is where is the best way to handle the response and return the result back to the component where i called the method from so I can manipulate the view to show either the success message or display an error message.
At the moment in my service under login I am currently not handling the response I am simply doing a callback back to the original component but I feel this isnt the correct way to go about it? Can someone shed some light on what they would do in this typical scenario? Would I handle the response in the first parameter of the subscribe function like:
login(user: User, done: Function) { var postData = "email=" + user.email + "&password=" + user.password; this.headers = new Headers(); this.headers.append('Content-Type', 'application/x-www-form-urlencoded'); this.http.post('/auth/local', postData, { headers: this.headers }) .map((res:any) => res.json()) .subscribe( (data) => { // Handle response here let responseStat = this.handleResponse(data.header) // Do some stuff this.saveJwt(data.id_token); // do call back to original component and pass the response status done(responseStat); }, err => this.logError(err) ); } handleResponse(header) { if(header.status != 401) { return 'success' } return 'error blah blah' }
Is a call back fine in this case or can this be handled better with an observable or a promise?
Concluding what I am asking is... What is the best practice to handle the response from the http response and handle the status in the view of the form from the user.service.ts back to the login-form.component.ts