2016-03-31 12 views
13

Ich habe einen Dienst mit einer beglaubigen Funktion -Angular 2 Rückgabedaten aus RxJs abonnieren

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; 
    } 

Also, wenn ich die authenticate Funktion console.log(authenticate('a', 'b')); nennen, es meldet sich undefined da die ret Variable vor der Zeichnung Funktion zurückgegeben wird, kann lege die Daten hinein. Wie kann ich die HTTP-Antwortdaten von der Authentifizierungsfunktion zurückgeben? Ich habe noch nie eine reaktive Programmierung mit RxJS gemacht und das ist es, was angular 2 zu benutzen scheint.

PS. Gibt es eine anständige CSP-Lösung für Javascript wie go Kanäle oder core.async?

+1

Das ist nicht wirklich, wie async oder RxJs funktioniert; Sie geben keine Daten von asynchronen Funktionen zurück. –

+0

so viel ich dachte, da abonnieren wird ausgeführt, nachdem ich die Ret-Variable zurückgeben. irgendwelche Ideen, wie ich Daten zurückgeben kann, wenn ich mit RxJS handle? – Lordking

+0

Sie könnten eine andere Methode erstellen, sagen this.authenticateFinished (ret) {console.log (ret); // und alles andere} und rufe dann dieses aus data => {} – philoniare

Antwort

11

benutzte ich Observable und Beobachter um meine Lösung zu bauen. Da @Injectable eine Singleton-Klasse erstellt, habe ich in ihr ein Observable-Objekt deklariert, das ich dann meiner Komponente zugänglich gemacht habe. Wenn ich irgendwelche Daten hineinlege, werden alle Abonnenten von der Veranstaltung benachrichtigt. Warnung: Wenn Sie dies mit zone.js 0.5 verwenden, wird es nicht funktionieren. Funktioniert mit 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 => { 
       ... 
      } 
     ) 
    } 
} 
+0

Was ist die Benachrichtigung in "Privatbeobachter: Beobachter " Was kann ich an Observer übergeben? –

+0

ersetzen Sie einfach mit – Sebastian

3

Sie müssen direkt die beobachtbare entsprechenden Ihre Anfrage zurück:

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()); 
} 

und der Anrufer der authenticate Methode auf sie zeichnen möchten, müssen Sie das Ergebnis erhalten:

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

Danke dafür. Ich wollte jedoch, dass die gesamte Logik in einen Service statt in eine Komponente integriert wird. Ich habe es herausgefunden. – Lordking