web-dev-qa-db-fra.com

Angular 2 - Renvoie des données directement à partir d'un observable

Je me suis cogné la tête contre celui-ci pour essayer de comprendre, et aucune quantité de documentation que j'ai pu lire n'a donné de réponse à ma question.

J'ai un service qui parle directement à une API et renvoie un événement observable auquel, dans des circonstances normales, je m'abonne et fais ce que je veux avec les données, mais dans un service secondaire qui utilise les demandes du service reposant, je dois pouvoir renvoyer des valeurs de la requête.

getSomething() {
    return this._restService.addRequest('object', 'method').run()
        .subscribe(
            res => {
                res;
            },
            err => {
                console.error(err);
            }
        );
}

returnSomething() {
    return this.getSomething();
}

Dans l'exemple rapide ci-dessus, je veux savoir s'il est possible de retourner res à partir de getSomething() dans returnSomething(). Si ce n'est pas réalisable de cette manière, quelle est l'alternative? J'ajouterai que le _restService est assez largement utilisé et je ne veux pas vraiment commencer à jouer avec ça.

29
Sidriel

Comme les appels http et autres sont asynchrones, vous obtenez un Observable au lieu d’une valeur synchrone. Vous devez vous y abonner, et dans le rappel, vous obtenez les données. Il n'y a pas de chemin aux alentours.

Une option serait de placer votre logique dans l'appel subscribe

getSomething() {
    return this._restService.addRequest('object', 'method').run()
        .subscribe(
            res => {
                // do something here
                res;
            },
            err => {
                console.error(err);
            }
        );
}

Mais ce que j'aime faire, c’est d’ajouter un rappel, d’injecter la logique de l’extérieur (peut-être un composant, un autre service):

getSomething(callback: (data) => void) {
    return this._restService.addRequest('object', 'method').run()
        .subscribe(
            res => {
                callback(res);
            },
            err => {
                console.error(err);
            }
        );
}

Et dans votre composant ou ailleurs:

this._yourService.getSomething((data) => {
    // do something here
    console.log(data);
});
42
rinukkusu

Je ne l'ai pas utilisé moi-même, mais je crois que cela devrait fonctionner en théorie (:

// service.ts
getSomething() {
  let subject: Subject = new Subject();
  this._restService.addRequest('object', 'method').run()
    .subscribe(subject);
  return subject;
}

// this can be removed (;
returnSomething() {
  return this.getSomething();
}

// component.ts
ngOnInit() {
  this.service.returnSomething()
    .subscribe(res => console.log(res), err => console.log(err));
}

Vérifiez documentation sujet pour plus d'informations. Vous pouvez utiliser différents types de sujet, par exemple BehaviorSubject a la propriété value à laquelle vous pouvez accéder ...

ngOnInit() {
  // if you use BehaviorSubject
  this.service.returnSomething().value
}

Voici le plunker de travail ...

1
Sasxa

J'ai eu un problème similaire. Ma solution a été de convertir l'observable en une promesse avec .toPromise () (et d'utiliser async - attend de le retourner et de corriger les erreurs). Vous pouvez convertir votre code en quelque chose comme:

 async getSomething() {
     try{
         return await this._restService.addRequest('object', 'method').run().toPromise()
      } catch (err){
       console.error(err);
          }
  }
0
hjbello