Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

250
Visualizações
How to avoid observable calculation on each subscription?

I have the next code:

this.currency$ = combineLatest([
  this.currency.valueChanges, // Currency ID Form Control (selected currency id)
  this.currencies$, // A list of currencies, that is loaded from backend
]).pipe(
  map((result: [number, Currency[]]) => {
    // todo: optimize - do not loop over all, stop when found
    let currencyName = '';
    if (result[1]) {
      result[1].forEach((currency: Currency) => {
        if (currency.id === this.currency.value) {
          currencyName = currency.name;
        }
      });
    }

    return currencyName;
  })
);

The problem is, when I subscribe in the template to the currency$ observable, using the | async pipe - The calculation (determination of the currency name) happens twice.

What is a good solution, to calculate it only once and on every subscription, emit already calculated currency name? Of course I could add a component variable and preserve name there, but I would like to use observables, so the component should not have it's own state...

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

You can avoid this by using shareReplay Operator https://www.learnrxjs.io/learn-rxjs/operators/multicasting/sharereplay to share the source and it the calculation will be done just once

  import { map, shareReplay } from 'rxjs/operators';
  ...


  this.currency$ = combineLatest([
  this.currency.valueChanges, // Currency ID Form Control (selected currency id)
  this.currencies$, // A list of currencies, that is loaded from backend
]).pipe(
  map((result: [number, Currency[]]) => {
    // todo: optimize - do not loop over all, stop when found
    let currencyName = '';
    if (result[1]) {
      result[1].forEach((currency: Currency) => {
        if (currency.id === this.currency.value) {
          currencyName = currency.name;
        }
      });
    }

    return currencyName;
  }),
  shareReplay() // here 
);

on this other hand avoid using multiple async pipe on your template, you can use an ng-container to set the value of your async pipe result to a variable and use it everywhere in your template

<ng-container *ngIf="currency$ | async as curency">
  // use currency here
</ng-container>
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda