2

I can display a value produced by an Observable using {status_async | async} in html.

However, how can I test whether this Observable is equal to something?

Specifically, I'd like to use it to assign a class:

<div [ngClass]="{'has-danger': status_async == 'created before'}">
    <input type="text">
</div>

I discovered that I can use:

<div [ngClass]="{'has-danger': (status_async | async) == 'created before'}">

But then the issue becomes that I have used async twice (here and for displaying the value).

As I'm checking the status of a succesful creation, ironically after the second async the value changes to 'created before', even when I clicked my create button only once.

How can I solve this issue?

PascalVKooten
  • 20,643
  • 17
  • 103
  • 160
  • In your Observable use [`share()`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/share.md) to avoid subscribing twice. – Eric Martinez Feb 21 '16 at 13:50

1 Answers1

2

You need to be careful when using several async pipe on the same observable since this means that there are now several subscribers on it (the subscribe method is called several times, one per use of the async pipe).

In the case of an observable created from an HTTP call, the corresponding request will be called twice if subscribed twice)... By default such observables are cold (they can't be shared).

You need to make your observable hot using the share method:

this.status_async = this.status_async.share();
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • I'm `return`ing from `http.post.map()` and then in the view `{ status_async | async}`. I noticed `this.status_async = this.status_async.share();` doesn't work then anymore afterwards. – PascalVKooten Feb 21 '16 at 14:27
  • You set the return of the map method into the status_async property? Did you add the share operator like the map one? – Thierry Templier Feb 21 '16 at 14:31
  • Simply do the following: http.post(...).map(...).share(). This should work. – Thierry Templier Feb 21 '16 at 14:35
  • See this answer: http://stackoverflow.com/questions/34677947/converting-angular2-http-response-to-connectableobservable/34678117?s=0|1.6248#34678117 – Thierry Templier Feb 21 '16 at 14:51
  • 1
    To import the share operator: import 'rxjs/add/operator/share'; – Thierry Templier Feb 21 '16 at 14:53
  • `this.status_async` is being set to the return `this.http.post().map(request => "Created: " + request.json().created).share();`. Then when I want to `{{result}}` (instead of `{{result | async}}`) and it shows `[object Object]`. Previously it showed the string though. – PascalVKooten Feb 21 '16 at 16:16
  • How do set the result? Within a subscribe? I mean something like: `this.http.post().map(...).share(...).subscribe((data) => { this.result = data; });` – Thierry Templier Feb 21 '16 at 17:01
  • Sharing the observable shouldn't have impacts on the received data. I would be interested in the code you use to set the `result` property. – Thierry Templier Feb 21 '16 at 17:13