web-dev-qa-db-fra.com

Angular2 Observable et Promise

J'ai commencé à utiliser Angular2 Observable, mais je ne trouve pas quelque chose de similaire à .then que j'ai utilisé avec Promises.

C'est ce que je veux accomplir.

code de header.component.ts

public login() {
    this._user = AuthService.getInstance().login(this._loginInfo);
}

code de auth.service.ts

return this._httpClient.post('LoginAction', credentials)
  .map(res => res.json())
  .subscribe(user => {
    return new User(user);
  });

Avec les promesses, la fonction login renverrait Promise, qui serait éventuellement transformée en réponse réelle du serveur. Mais avec Observable, cela ne fonctionnera pas.

Y a-t-il un moyen de faire la même chose? Je veux éviter d'avoir à mettre subscribe dans la fonction component de login. Je veux être capable de faire tout le travail en service et de retourner l'objet réel à component.

De plus, j'ai essayé de créer Promise, avec toPromise, mais je continue à obtenir toPromise is not a function.

p.s. _httpClient est mon enveloppe autour de http angular2 dans lequel je prépare la demande en ajoutant des en-têtes, etc.

modifier

return this._httpClient.post('LoginAction', credentials)
  .map(res => res.json())
  .toPromise().    <-- i keep getting that it is not a function
  then(user => {
    return new User(user);
});

en faisant cela, mon composant obtiendra un objet (ce qui est ce dont il a besoin), et dans le service, je pourrais faire des choses supplémentaires (comme enregistrer l’utilisateur sur le stockage local, une fois que je l’ai connecté).

Et je suis passé à Promise, parce que faire la même chose avec Observable ne fonctionne pas (ou je le fais mal)?

Je vois que l'objet renvoyé est Observable (avant d'appeler toPromise), mais je ne vois pas la fonction toPromise en effet.

35
Ned

Lorsque vous appelez subscribe(...), un Subscription est renvoyé sans toPromise(). Si vous déplacez le code de subscribe vers map, vous pouvez utiliser toPromise() au lieu de subscribe.

return this._httpClient.post('LoginAction', credentials)
  .map(res => res.json())
  .map(user => {
    return new User(user);
  }).toPromise();

et l'appelant obtiendra un Promise où il pourra obtenir la valeur à l'aide de

public login() {
    this._user = AuthService.getInstance().login(this._loginInfo)
    .then(result => {
      doSomething();
    });
}

mais vous obtenez le même résultat si vous omettez `.toPromise () et que l'appelant l'utilise comme

public login() {
    this._user = AuthService.getInstance().login(this._loginInfo)
    .subscribe(result => {
      doSomething();
    });
}

où la seule différence est subscribe() au lieu de then() et si l'utilisateur de la bibliothèque préfère le style réactif, il préférera utiliser subscribe() comme il en a l'habitude.

33
Günter Zöchbauer

Vous devez importer l'opérateur Rx toPromise tel que

import 'rxjs/add/operator/toPromise';

À votre santé!

22
dheeran

De la documentation Angular2

Nous vous conseillons d’ajouter ceci dans rxjs-extension.ts

```
// Observable class extensions 
   import 'rxjs/add/observable/of'; 
   import 'rxjs/add/observable/throw';

// Observable operators 
   import 'rxjs/add/operator/catch'; 
   import 'rxjs/add/operator/debounceTime'; 
   import 'rxjs/add/operator/distinctUntilChanged'; 
   import 'rxjs/add/operator/do'; 
   import 'rxjs/add/operator/filter'; 
   import 'rxjs/add/operator/map'; 
   import 'rxjs/add/operator/switchMap'; 
```

Et importez-le à app.module.ts (Module racine) import './rxjs-extensions';

Cela nous aidera à éviter d’autres erreurs.

2
YoongKang Lim