Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

292
Vistas
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?

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

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();
about 4 years ago · Juan Pablo Isaza Denunciar

0

I like the answer that @Joshua McCarthy provided but you don't need to subscribe at all and you can get a "cleaner" (depending from the point of view of the consumer) version.

Kudos for the statement about the shareReplay(1) to avoid extra side-effects (which they are usually API calls, resulting in undesired network consumption). I highly suggest you apply it to your image options observable.

then I would proceed to create another observable:

import { combineLatest, shareReplay } from 'rxjs/operators'

@Component({...})
export class YourComponent {
    ...
    ...
    selectedImageVolumeSize$ = combineLatest([this.createVmForm['image'].valueChanges, this.imagesOptions$]).pipe(
        map(([selectedImageId, imageOptions] => imageOptions.find(item => item.id === selectedImageId)

    )

    constructor(...){}

}
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda