Read value of observable with subscribing to it
I have an observable like
imageOptions$: Observable<BoundImagesToProject[]> = this.imagesService
.getBoundImages({ projectId: this.projectId })
.pipe(map((images) => (images.data)));
and in the template I use it like
<div class="form-field input-group">
<label for="image">Image</label>
<mat-select id="image" class="select--full-width" placeholder="Image" formControlName="image">
<mat-option *ngFor="let image of imageOptions$ | async" [value]="image.imageId">
{{ image.name }}
</mat-option>
</mat-select>
<mat-error *ngIf="createVmForm.get('image').getError('required') && createVmForm.get('image').dirty"
>Field is required</mat-error
>
</div>
Now I want to use the imagesOptions$ observable in the TS file like
this.imageChangeSubscription = this.createVmForm.get('image').valueChanges.subscribe((value) => {
this.selectedImageVolumeSize = this.imagesOptions$ // get array value and match id and get the size.
If it was an array it would be like
this.selectedImageVolumeSize = this.images.find((image) => image.imageId === value).size;
I want to do it without subscribing to imageOptions$ observable in the imageChangeSubscription to avoid subscribtion in side subscription and without using an extra property in the TS file
Any way to do it?
Solution 1:
You can use switchMap()
to avoid nested subscriptions. But you should update imagesOptions$
so it can share its latest value with multiple subscribers using the shareReplay()
operator.
imageOptions$: Observable<BoundImagesToProject[]> = this.imagesService
.getBoundImages({ projectId: this.projectId })
.pipe(
map(({data}) => data),
shareReplay(1)
);
Then in your subscription, grab the latest value from imageOptions$
to find your size.
this.imageChangeSubscription = this.createVmForm
.get('image').valueChanges
.pipe(
switchMap(value => this.imagesOptions$
.pipe(
map(images => images.find(({imageId}) => imageId===value ))
)
)
).subscribe();