Utilizing the await keyword within a forkJoin operation in TypeScript

I am facing an issue where I need to fetch a new result based on the old result. When a specific parameter in my primary call is X, it should trigger another function. However, the problem I'm encountering is that the scope of the program continues running, leading to the loss of the new parameter.

Here's how the code appears:

export class DashboardGuard implements CanActivate { 


 public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { 
    this.logger.info(DashboardGuard::canActivate());
    return Observable.create((subscribe: Subscriber<boolean>): void => { 


    Observable.forkJoin(
                this.mapSettingsService.fetch(),
                this.userSettingsService.fetch(),
                this.mapFenceService.fetch(),
                this.markersMotesService.fetch(),
                this.markersStaticsService.fetch()
            ).subscribe((result: [MapSettings, UserSettings, MapFenceGroup[], MarkersMotes, MarkersStatics]): void => {

                // Retrieve loaded motes and statics
                const mapSettings: MapSettings = result[0];
                const userSettings: UserSettings = result[1];
                const mapFenceGroups: MapFenceGroup[] = result[2];
                let markersMotes: MarkersMotes = result[3];
                const markerStatics: MarkersStatics = result[4];

                for (let i in markersMotes.items) {
                    if (markersMotes.items[i].longitude === 0 || markersMotes.items[i].latitude === 0) {
                        // In this scenario, I need to trigger another fetch using data from previous fetch calls, but the program scope needs to wait until those fetch calls complete.
                        //  Example of fetch:
                        Observable.forkJoin(
                            this.markersMotesService.newfetch(markersMotes.items[i].macAddress),
                        ).subscribe((result: [MarkersNolocations]): void => {
                            const newResult: MarkersNolocations = result[0];
                            if (newResult.missedCounter > 0) {
                                markersMotes.items[i].latitude = 10;
                                markersMotes.items[i].longitude = 10;
                            }
                        });

                    }
                }
})

While forkjoin works great for retrieving all calls at once, what about nested calls within it?

Any assistance on this matter would be highly appreciated!

Best regards,

Bram

Answer №1

It is recommended to avoid nested subscriptions and opt for chaining operators instead. Using switch map allows you to transfer the output of one observable to the input of another.

Check out more about switch map here

I have made modifications to your code by implementing switchMap. Although I'm not certain about the structure of your MarkerMotes class, this should provide you with a starting point.

let itemsRequiringLocation: SomeClassHere[] = [];
Observable.forkJoin(
                this.mapSettingsService.fetch(),
                this.userSettingsService.fetch(),
                this.mapFenceService.fetch(),
                this.markersMotesService.fetch(),
                this.markersStaticsService.fetch()
            ).switchMap((result: [MapSettings, UserSettings, MapFenceGroup[], MarkersMotes, MarkersStatics]): void => {

                // Retrieve loaded motes and statics
                const mapSettings: MapSettings = result[0];
                const userSettings: UserSettings = result[1];
                const mapFenceGroups: MapFenceGroup[] = result[2];
                let markersMotes: MarkersMotes = result[3];
                const markerStatics: MarkersStatics = result[4];
                let obs: Observable[] = [];

                for (let i in markersMotes.items) {
                    if (markersMotes.items[i].longitude === 0 || markersMotes.items[i].latitude === 0) {
                        itemsRequiringLocation.push(markersMotes.items[i]);
                        obs.push(this.markersMotesService.newfetch(markersMotes.items[i].macAddress));
                    }
                }
                return Observable.forkJoin(obs);
            }).subscribe((result: [MarkersNolocations]): void => {
                itemsRequiringLocation.forEach((item, index) => {
                    if (result[index].missedCounter > 0) {
                        item.latitude = 10;
                        item.longitude = 10;
                    }
                });
            });

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating a React component with a reference using TypeScript

Let's discuss a scenario with a reference: someReference; The someReference is essentially a React component structured like this: class SomeComponent<IProps> { getData = () => {}; render() { ...some content } } Now, how c ...

Issue: [ts] Unable to locate the term 'React'

Due to specific requirements, I have made some customizations to the Ionic component: range. I changed the class name of the component from Range to CustomRange (with selector: custom-range): https://github.com/ionic-team/ionic/blob/master/core/src/compon ...

Choose does not showcase the updated value

My form contains a form control for currency selection Each currency object has the properties {id: string; symbol: string}; Upon initialization, the currency select component loops through an array of currencies; After meeting a specific condition, I need ...

Typescript interface designed for objects containing certain optional property names as well as unspecified property names

I am looking to design an interface for an object that can have optional properties with specific names, as well as accept properties with arbitrary names. Here is my approach: interface CallBack { onTransition?(): any; // option A [key: string]: () = ...

Implementing a unique sorting algorithm for an array of numbers in Angular

I need to organize an array of numbers in descending order with a custom sorting method based on a specified number, all without splitting or filtering the array. I am currently working with Angular 17 and Rxjs 7.8. For instance, if I have this array of n ...

Angular, perplexed by the output displayed in the console

I'm completely new to Angular and feeling a bit lost when it comes to the console output of an Angular app. Let me show you what I've been working on so far! app.component.ts import { Component } from '@angular/core'; @Component({ ...

Performing DTO validation in the controller before passing data to the service

My current challenge involves implementing validation in a PUT request to update data stored in MongoDB: DTO: export enum reportFields { 'startDate', 'targetDateOfCompletion', 'duration', } export class updateS ...

Employing an unchanging Map format for observation

I'm currently working on implementing a synchronization mechanism using observable and Map structures from Immutable.js. However, I'm encountering an issue where the Map is unable to function as an observable or perhaps I might be approaching it ...

What is the best way to assign a variable with the type (x:number)=>{y:number,z:number}?

I am trying to initialize a variable called foo, but my current code is not compiling successfully. let foo: (x: number) => {y:number,z: number} = (x) => {x+1, x+2}; This results in the following error: Left side of comma operator is unused and ha ...

Attempting to create distinct match matchups for every team in a manner reminiscent of the Swiss system format used in the 2024/25 UEFA Champion League

I've been working on devising a tournament pairing system modeled after the updated UEFA Champion League structure. The league phase involves 36 teams, categorized into 4 different pots. Each team is scheduled to play a total of 8 matches against 2 op ...

Tips for creating a flexible popover widget

I am facing an issue with my project that has a popover (ng-bootstrap) similar to what I need. The problem is that the tooltips and popovers are not flexible when it comes to resizing the page. To address this, I attempted to put a mat-grid (which works pe ...

Issue: NullInjectorError occurred while running a unit test case due to StaticInjectorError in DynamicTestModule for the platform dependency

Encountering an error while running unit tests for a component: NullInjectorError: StaticInjectorError(DynamicTestModule)[platform]: StaticInjectorError(Platform: core)[platform]: NullInjectorError: No provider for platform! describe('ChangesGridComp ...

The Vue3 module does not have any exported members available

I am seeking assistance with a Vue component. I have encountered an error message that states: Failed to compile. src/components/Btn/Btn.vue:11:14 TS2305: Module '"../../typings/button-type"' has no exported member 'ButtonType&apo ...

The presence of 'touched' within Angular validation is causing a delay in method execution

Upon utilizing this validation method, it became apparent: <label>Password</label> <input type="password" formControlName="password" class="form-control" [ngClass]="{ 'is-invalid': f.password.touc ...

What are the best practices for effectively using RxJs subscriptions?

I'm looking for some advice on how to handle Angular and RxJs mechanics. I have server-side pagination set up on my backend and three components on the frontend: a data list, filters, and a pagination component. How can I subscribe to two streams (pag ...

The console date format does not match the input date format

I have successfully configured my date format to yyyy-MM-dd and I want my component to output the date in that specific format. The input field displays dates correctly, such as 2020-10-03, but when I use console.log(), it shows: endDate: Sat Oct 03 2 ...

Encountering difficulties with implementing reactive forms in an Ionic Angular 7 project as the app.module.ts file appears to be missing

Currently, I am working on a project using Ionic Angular 7 and I am facing some challenges with implementing reactive forms. Since app.module.ts is not in Ionic Angular 7 anymore, I tried to search for solutions online. Unfortunately, when I followed the i ...

Making sure that a commitment does not come to fruition

Perhaps this code snippet below functions correctly as it is, but I'm uncertain if it's the best approach to prevent potential runtime issues. Here's the code in question: const ep = `${environment.api.baseUrl}/login`; return this.http.pos ...

I'm wondering why my JWT token appears as null on the backend while it is not null on the frontend

I'm having trouble with a GET request to my mLab database. I included a JWT token in the request and verified it on both the client and server side. Strangely, it appears correctly on the client but as null on the server. Any assistance on this matter ...

getting requestParam of type date from angular using spring

Hello everyone, I am new to working with Angular and Spring. I am attempting to send a GET request with some date parameters, but I keep encountering an error. Here is the HTML code snippet: <div class="form-row"> <div c ...