Angulaire 2 données de retour de RxJs s'abonner

J'ai un service avec une fonction d'authentification –

authenticate(username: string, password: string) { let ret; let packet = JSON.stringify({ username: username, password: password }); let headers = new Headers(); headers.append('Content-Type', 'application/json'); this.http.post('http://localhost:5000/api/authenticate/', packet, { headers: headers }) .map(res => res.json()) .subscribe( data => { // put return data into ret ret = data.token; }, err => console.log(err), () => { // this works! console.log(ret); } ); // get's returned before I put data into it return ret; } 

Donc, si j'appelle la fonction d'authentification console.log(authenticate('a', 'b')); , Il se connecte undefined puisque la variable ret est renvoyée avant que la fonction de souscription ne puisse y mettre les données. Comment puis-je retourner les données de réponse http de la fonction d'authentification? Je n'ai jamais fait de programmation réactive avec RxJS avant et c'est ce que l'angulaire 2 semble utiliser.

PS. Existe-t-il une solution CSP décente pour javascript comme go channels ou core.async?

J'ai utilisé Observables and Observers pour construire ma solution. Puisque @Injectable crée une classe singleton, j'ai déclaré un observable à l'intérieur de celui-ci que j'ai ensuite exposé à mon composant. Lorsque j'ai mis des données, tous les abonnés sont informés de l'événement. Avertissement: si vous utilisez ceci avec zone.js 0.5, cela ne fonctionnera pas. Fonctionne avec 0.6.

 import {Observable} from 'rxjs/Observable'; import {Observer} from 'rxjs/Observer'; import 'rxjs/add/operator/share'; import 'rxjs/add/operator/map'; import 'rxjs/Rx'; @Injectable() export class AuthService { // expose to component notification$: Observable<Notification>; private observer: Observer<Notification>; .... constructor(private http: Http) { this.notification$ = new Observable(observer => this.observer = observer).share(); } authenticate({username, password}) { let packet = JSON.stringify({ username: username, password: password }); let headers = new Headers(); headers.append('Content-Type', 'application/json'); this.http.post(`${this.baseUri}/authenticate/`, packet, { headers: headers }) .map(res => res.json()) .subscribe( data => { if (data.success && data.token) { this.saveJwt(data.token); } else { this.deleteJwt(); } // put data into observavle this.observer.next({ message: data.message, type: data.success }); }, err => { // put data into observavle this.observer.next({ message: 'Error connecting to server', type: false }) }, () => {} ); } } export class AuthComponent implements OnInit { observable: Observable<Notification>; ... ngOnInit() { // subscribe to the observable this.observable = this.authService.notification$; this.observable.subscribe( data => { ... } ) } } 

Vous devez retourner l'observable correspondant à votre demande directement:

 authenticate(username: string, password: string) { let ret; let packet = JSON.stringify({ username: username, password: password }); let headers = new Headers(); headers.append('Content-Type', 'application/json'); return this.http.post('http://localhost:5000/api/authenticate/', packet, { headers: headers }) .map(res => res.json()); } 

Et l'appelant de la méthode d' authenticate doit s'y abonner pour recevoir le résultat:

 this.service.authenticate('username', 'password').subscribe( (result) => { console.log('Result received'); console.log(result); } );