Async not working for Subject.asObservable

Thank you for your insights. The stackblitz code is a contrived example of the behaviour I’m seeing. It’s not trying to do anything, it’s just attempting to show you something.

The tour of heroes tutorial you yourself reference, accesses injected service methods/properties directly from a component template. This would suggest it isn’t an anti-pattern.

  <div *ngFor='let message of messageService.messages'> {{message}} </div>

This template binds directly to the component’s messageService.

An Angular event binding binds the button’s click event to MessageService.clear()."

Having said that I am interested in knowing what you suggest as an alternative. I take your point that getters/methods shouldn’t be referenced in a template. But getters are minimalistic by design and in this case I’m not sure how to avoid it. I don’t want to directly reference the Subject. _connection$ is being updated by a separate service. And I want the UI to change based on its current state.

I’m moving away from utilising a state machine and wanted to directly tap the observable. Perhaps I’ll retain the FSM and update that with subscription. I have the notion that each component should be able to independently act on emissions from the data service _connection$ Subject. It comprises a couple of different sources so it makes good sense to have it in a shared service. Letting Angular manage the subscription in the template where it’s only function is to update same, seems to be the right thing.

Moreover, without digging into how aync subscriptions work, I had hoped it would access the getter once, retrieve the observable and wait for an emission. I didn’t think that it would ask for a new observable on each cycle.

Do you mean?

next: (count) => (this.fromSubscription = count)

It’s not what you think. I’m assigning the emissions of an observable to a poorly named numeric property. I did that to illustrate a component side subscription to the service observable that’s accessible from the template. That’s just troubleshooting.

Oh, do mean this bit in the stackblitz?

next: (i) => this._connection$.next(i)

It’s contrived, the actual inputs to the Subject come from UI interaction and bluetooth events. That was just a quick and nasty way of pumping mock data into the Subject.

I return the Subject asObservable, as you’ve alluded, to hide methods like next and avoid side effects. And I’m using a Subject to multicast information to multiple observers. There generally seems to be a lot of extraneous helper methods/operators in the rxjs space. And we managed to achieve all of the same functionality (to varying degrees) before adopting a declarative style of coding! :wink:

Nevertheless, it feels more idiomatic to use them where appropriate. In defence of asObservable, it makes the code look more deliberate. And if you trusted that the Subject won’t be abused further down the line, then why not just return it as a Subject and avoid the cast altogether?

So… any idea why async doesn’t pick up the stream?