0
votes

I am using the following pattern a lot in my Angular application. I have an observable that comes from an RxJs BehaviourSubject that has to be initialised with a value from another observable. I'd like to use it in an async pipe. The only way I can achieve this is like so:

    ngOnInit() {
    this.notificationService
        .getNotificationForOperationId(`${this.operation.operationId}`)
        .subscribe((notification: Notification) => {
            this.activitiesExists = notification?.activities;
        });
}

then I subscribe to changes to that variable:

    subscription = this.notificationService.notificationUpdated$
    .subscribe(() => {
        this.activitiesExists = true;
    });

I use the variable in my template:

 <ng-container *ngIf="activitiesExists">
   ...
</ng-container>

I'd rather use the variable with an async pipe like so:

 <ng-container *ngIf="activitiesExists | async">
   ...
</ng-container>

but I don't know how to define the variable in on RxJs statement. I am aware of the startWith() RxJs Operator, but it only accepts static values and not an observable.

I'd like to use something like this, but it seems it does not exist:

    this.activitiesExists = this.notificationService.notificationUpdated$.pipe(
        startWith(this.notificationService.getNotificationForOperationId(this.operation.operationId))
    );

Is there any way to achieve this behaviour ?

2
Not sure I understand your question. When you define your behaviourSubject you have to initialize with a default which can be of any type or even "any".Darren Street
I believe concating your 2 observables can workAndrei
Would a more declarative approach help? Something like covered here: youtube.com/watch?v=e2KAn50QBBw If you could build a short stackblitz that demonstrates the issue we can look into it further and provide a more specific reply.DeborahK

2 Answers

0
votes

Maybe something more of a declarative approach like this:

activitiesExists$ = this.notificationService
    .getNotificationForOperationId(`${this.operation.operationId}`)
    .pipe(
      map((notification: Notification) => notification?.activities)
    );
0
votes

Just in case someone's interested. It seems that I have figured it out :

        this.activitiesExist$ = this.notificationService
            .getNotificationForOperationId(this.operation.operationId)
            .pipe(
                switchMap((notification) =>
                    this.activitiesRecordingService.notificationUpdated$
                        .pipe(map((non) => non.operationId === this.operation.operationId))
                        .pipe(startWith(notification?.activities?.length > 0))
                )
            );

In the first step I get the current value (notifications for an operation) and immediately switchMap to updates on that value. There I use "startWith" to initialize the observable with the result from the first observable.