Home > Software engineering >  Track observables in combineLatest
Track observables in combineLatest

Time:02-25

I've inherited a code base that uses combineLatest and I'm trying to figure out if there is a way to track the inner observables to provide status updates to the UI as this is a long running process (i.e. greater than a few seconds).

I'm brand new to angular and rxjs - the code I'm looking at is below.

I don't think this needs to use combineLatest as all three are http requests so not returning multiple values.

Is there a better option for me to use so I can easily track the status and update the UI?

private vehiclesWithIssueData$() {
    let result = combineLatest(this.vehicles$, this.vehicleSpecs$, this.visInspMonData$()).pipe(
        map(w => Array.from(w[0].entries()).map(v => {
            let [vehicleId, vehicle] = v;
            let [vehicleMap, vehSpecMap, monitoringMap] = w;
            let monIssues = monitoringMap.get(vehicleId) || [];
            let spec = vehSpecMap.get(vehicle.specificationId);

            return <IDisplayVehicle>{
                serialNo: vehicle.serialNo,
                altText: monIssues.map(m => m.issueText).join("\n") || "No issues",
                application: spec?.vehicleApplication || "unknown",
                model: spec?.model || "unknown"
            };
        })),
    );
    return result;
}

CodePudding user response:

You can add a tap operator, before your map, and there you can view your data from the stream. As a tip, avoid using indexes when you’re using combineLatest, because it can cause problems in the future and it’s hard to maintain. (for example the data it might be chaged and your indexes will be invalidated)

CodePudding user response:

In your case, you can use many RxJS helper functions such as combineLatest, forkJoin, and concat, since all the inner Observable(s) are HTTP requests as you mentioned which will be completed directly after emitting their values.

And to track each one of the combined Observable(s), you can use the tap operator with each one of them, to enable/disable loading or whatever you need.

You can try something like the following:

// import { tap } from 'rxjs/operators';

const result = combineLatest(
  this.vehicles$.pipe(tap((vehicles) => console.log(vehicles))),
  this.vehicleSpecs$.pipe(tap((vehicleSpecs) => console.log(vehicleSpecs))),
  this.visInspMonData$().pipe(
    tap((visInspMonData) => console.log(visInspMonData))
  )
)

// ...

Read more about Observables & RxJS in Angular here: https://angular.io/guide/observables

  • Related