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

122
Visualizações
Modify data in stream used with angular async pipe reactive way

iam trying to use async pipes instead of manually subscribing in components, in case, iam just displaying data which i get from server, everything works fine. But what if i need to change displayed part of displayed data later, based on some event?

For example, i have a component which displays timetable, which can be later accepted by user. I create timesheet$ observable and i use it in my template with async pipe. For accepting i created subject, so i can emit, when user accepts the timesheet. But how do i combine these two streams(approvementChange$ and timesheet$), so the $timesheet gets updated? I was trying combineLatest, but it returns the latest values, so i cant decide, if the value from approvementChange stream is new or old. Any ideas how to solve this?

export class TimesheetComponent {
  errorMessage: string = '';
  timesheet$: Observable<Timesheet>;
  
  private approvementSubject = new Subject<TimesheetApprovement>();
  approvementChange$ = this.approvementSubject.asObservable();

  constructor(
    private planService: PlanService,
    private statusService: StatusService,
    private notifService: NotificationService
  ) {}

  this.timesheet$ = this.statusService.appStatus.pipe(
    switchMap((status) => {
      return this.planService.getTimesheet(
        status.selectedMonth,
        status.selectedAgency.agNum
      );
    })
  ); //get data every time user changed selected month

  approveTimesheet(isApproved: boolean = true) {
    const approvement: TimesheetApprovement = {
      isApproved: isApproved,
      approveTs: new Date(),
      isLock: true,
    };
    this.approvementSubject.next(approvement);
  }
}
about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

But what if i need to change displayed part of displayed data later, based on some event?

RxJS provides lots of operators for combining, filtering, and transforming observables.

You can use scan to maintain a "state" by providing a function that receives the previous state and the newest emission.

Let's look at a simplified example using a generic Item interface:

interface Item {
  id         : number;
  name       : string;
  isComplete : boolean;
}

We will use 3 different observables:

  • initialItemState$ - represents initial state of item after being fetched
  • itemChanges$ - represents modifications to our item
  • item$ - emits state of our item each time a change is applied to it
  private itemChanges$ = new Subject<Partial<Item>>();

  private initialItemState$ = this.itemId$.pipe(
    switchMap(id => this.getItem(id))
  );

  public item$ = this.initialItemState$.pipe(
    switchMap(initialItemState => this.itemChanges$.pipe(
      startWith(initialItemState),
      scan((item, changes) => ({...item, ...changes}), {} as Item),
    ))
  );

You can see we define item$ by piping the initialItemState$ to the itemChanges$ observable. We use startWith to emit the the initialItemState into the changes stream.

All the magic happens inside the scan, but the set up is really simple. We simply provide a function that accepts the previous state and the new change and returns the updated state of the item. (In this case, I'm just naively apply the changes to the previous state; it's possible this logic would need to be more sophisticated for your case.)

This solution is completely reactive. The end result is a clean item$ observable that will emit the updated state of the current item (based on id), whenever the id changes or the changes occur on the item.

Here's a StackBlitz where you can see this behavior.

about 4 years ago · Juan Pablo Isaza Relatório

0

you need to track only approvementChange

after that you can pick the latest timesheet via withLatestFrom

approvementChange$
.pipe(withLatestFrom(this.timesheet$))
.subscribe(([accepted, latestTimesheet]) => accepted ? save(latestTimesheet) : void 0)
about 4 years ago · Juan Pablo Isaza 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