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

Unable to generate Angular project using the command "ng new app_name" due to error code -4058

Whenever I try to run the command ng new app-name, I encounter error -4058. If I execute the same command while opening cmd as an administrator in the directory C:/Windows/system32, the project creation process goes smoothly. However, if I change the dire ...

Using ThreeJS to Apply Dual Materials to a Mesh Entity

With ThreeJS, it's possible to incorporate more than one material into an Object3D/Mesh as stated in the documentation. You can either utilize a single Material or an array of Material: Class declaration and constructor for Mesh TypeScript file (exce ...

Alert me in TypeScript whenever a method reference is detected

When passing a function reference as a parameter to another function and then calling it elsewhere, the context of "this" gets lost. To avoid this issue, I have to convert the method into an arrow function. Here's an example to illustrate: class Mees ...

How can you assign a strokeStyle color to a Canvas using a CSS property?

Our team is currently working on an Angular2 / Ionic 2 project where we have implemented a HTML Canvas element that allows users to draw on it. One challenge we are facing is how to set the Canvas strokeStyle property using a color provided by a CSS style. ...

Encountered an error while attempting to install the DataTables npm package in an Angular

I am trying to add datatables to my angular application. Upon running ng add angular-datatables An error code is displayed (refer to the image). error image The cause of this error is unknown to me. Please review the package.json file as well. package.j ...

Angular 2 fails to redirect to a 404 page if both the route parameter and address are not valid

Currently, while working on my application with Angular 4.1.1, I have a habit of declaring routing in every module I create. For instance, in the file new-cars.routing.module.ts: import { NgModule } from '@angular/core'; import { RouterModule, ...

Issue encountered: Unable to access the property 'loadChildren' as it is undefined, while attempting to configure the path

How can I conditionally load the route path? I've attempted the code below, but it's throwing an error. Can someone guide me on how to accomplish this task? [ng] ERROR in Cannot read property 'loadChildren' of undefined [ng] i 「w ...

Is it possible to dynamically adjust the size of the CircleProgressComponent element in ng-circle-progress?

For my current Angular 11 project, I am facing the challenge of dynamically changing the size of the ng-circle-progress library's CircleProgressComponent element. After some research, I discovered that the element's size can be adjusted by apply ...

Struggling to implement a singleton service in Angular as per the documentation provided

I have implemented a service in Angular that I want to be a singleton. Following the guidelines provided in the official documentation, I have set the providedIn property to "root" as shown below: @Injectable({ providedIn: "root" }) export class SecuritySe ...

Creating a PDF file with Angular 7: A step-by-step guide

I need to create a PDF report using data provided by the user and save it in an object. I've encountered methods that involve creating an HTML page, taking a screenshot, and then converting it to PDF. However, I'm seeking a solution to generate a ...

How can I incorporate a child component into a separate component within Angular version 14?

Currently working with Angular 14 and facing a challenge with including a child component from another module into a standalone component. The structure of the standalone component is as follows: <div> <child-component></child-component& ...

What are the steps for launching an Angular application?

Running on ubuntu 18.0.4, I had angular-cli installed. Attempting to create a new app named conFusion using the command: ng new conFusion -dir=./conFusion --style=scss. CREATE conFusion/README.md (1026 bytes) CREATE conFusion/angular.json (3666 by ...

What are the steps to integrate <br> in a JavaScript code?

I have recently started learning about web development and I'm facing a challenge with this implementation. var obj = [[{ name: "John", age: 30, city: "New York"}, { name: "Ken", age: 35, city: "New Orleans"}]]; ...

What is the best way to set the typing of a parent class to the child constructor?

I am seeking a method to inherit the parameter types of a parent's constructor into the child's constructor. For example: class B extends A { constructor (input) { super(input); } } I attempted the following: class B extends ...

The type of Object.values() is not determined by a union or Records

When utilizing TypeScript, the Object.values() function encounters issues in deducing the accurate type from a union of Records: type A = Record<string, number>; type B = Record<string, boolean>; function func(value: A | B) { const propert ...

Guide to integrating Mongoose typings with Angular 2 webpack starter

As a newcomer, I'm hoping this issue is straight forward. I am currently utilizing the angular2-webpack-starter found on GitHub. Based on the mongoose documentation, it appears that including their JavaScript file allows for accessing a global varia ...

Issues arise when trying to implement Angular class and it does

I'm currently facing some challenges using classes in Angular to simplify my coding process. So far, I haven't been able to get it to work properly. Below is the code snippet I'm working with and the error message that pops up: import { Wiz ...

Assuming control value accessor - redirecting attention

import { Component, Input, forwardRef, OnChanges } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; @Component({ selector: 'formatted-currency-input', templateUrl: '../v ...

The Angular route functions flawlessly in the development environment, but encounters issues when deployed to

I have a project built with Angular 2, During development on localhost, everything runs smoothly. However, once I build a production version using (npm run build: prod) and navigate to the route on the server, I encounter a 404 error indicating that the r ...

Just recently updated to Angular 14 and I'm encountering a problem with images not loading from the assets folder. I'm wondering if there is a configuration step I missed. Could someone please

https://i.stack.imgur.com/4LEQ4.png https://i.stack.imgur.com/3sxzF.png Is there a configuration missing in Angular 14? When I try using <img [src]="assets/images/sidebarNav"> with ./, ../, it doesn't work. I have followed the instr ...