How to get a form control valueChanges value before subscription?

Issue

Hi I have a parent form control and a child component. The child component is not displayed until the parent form control has changed, e.g.:

<div *ngIf="parentControlChanged">
  <ChildComponent [value]="parentChanged$ | async"></ChildComponent>
</div>

As you can see, the child component is using an async pipe to get the value from the parent control (here parentControlChanged is a boolean state to indicate the parent control is first changed and parentChanged$ is just a pipe of the parentControl.valueChanges with some additional side-effects unrelated to this question).

The issue is the child component is not displayed until the parent control has changed, and hence not subscribed to the valueChanges yet, and hence not getting the changed value of the parent control. Otherwise, the child component is getting every subsequent change value of the parent control once it is displayed.

So is there a way for the child component to get the latest/current value of the parent control once it subscribes to the valueChanges with async pipe just like subscribing to a BehaviorSubject?

Solution

If something else is already subscribed to addition to parentChanged$ then, in addition to the side effects you didn’t go into, pipe shareReplay(1) at the end of it.

Then, as long as parentChanged$ is already subscribed to, when the child component or anything else subscribes to it, it will initially get the last-emitted value and any side effects will still be executed once, not once per subscriber.

If parentChanged$ isn’t already subscribed to then you either have to always subscribe and do the above, or change to a pattern where you do something like changing xyz.valueChanges to concat(defer(() => of(xyz.value)), xyz.valueChanges) so that when you subscribe, it starts with the initial value you want to send, then sends changes.

Answered By – JSmart523

Answer Checked By – Gilberto Lyons (AngularFixing Admin)

Leave a Reply

Your email address will not be published.