Dynamic Subscriptions in Angular 8/9: A guide to automatically using forkJoin with Observables from a dynamic collection

Initiate First Step:

Envision an entity named RouteObservables residing somewhere within the project that I aim to utilize (import) across multiple components:

export const RouteObservables = {
  state$: 'this.route.paramMap.pipe(map(() => window.history.state))',
  url$: 'this.route.url',
  params$: 'this.route.params',
  queryParams$: 'this.route.queryParams',
  fragment$: 'this.route.fragment',
  data$: ' this.route.data'
};

Proceed to Second Step:

To achieve the following scenario (using the above RouteObservables object):

 const state$ = this.route.paramMap.pipe(map(() => window.history.state));
 const url$ = this.route.url;
 const params$ = this.route.params;
 const queryParams$ = this.route.queryParams;
 const fragment$ = this.route.fragment;
 const data$ = this.route.data;

Advancing to Third Step

Employing the same collection RouteObservables to automatically commence a forkJoin:

forkJoin([...Object.keys(RouteObservables)]).subscribe(
  (routeData: any) => {
    this.routeData = routeData;
  }
);

Reason for Utilizing the RouteObservables object:

I require the organized sequence to access accurate data (e.g., routeData[0] being my potentially transferred state from the preceding route). This object prevents me from overlooking subscriptions to unsubscribe at the end (ngOnDestroy) as well.

Questions Arising:

  • What is the most effective method to declare Observables in a sequence (of interest) in an object (or collection) to perform operations dynamically?

  • If there is no established (modern) method, how can I smoothly progress from the first step to the second step?

  • Can I bypass the second step entirely and reach the third step more elegantly?

Edit1:

Note: forkJoin does not operate with route (ActivatedRoute) observables in this manner, as route observables do not complete. The following approach works, but my inquiries persist:

// snippet!
// routeData is a public property 

ngOnInit() {
    this.getAllRouteData();
}

getAllRouteData() {
  const state$ = this.route.paramMap.pipe(map(() => window.history.state));

  const url$ = this.route.url;
  const params$ = this.route.params;
  const queryParams$ = this.route.queryParams;
  const fragment$ = this.route.fragment;
  const data$ = this.route.data;

  forkJoin(
    state$.pipe(first()),
    url$.pipe(first()),
    params$.pipe(first()),
    queryParams$.pipe(first()),
    fragment$.pipe(first()),
    data$.pipe(first())
  ).subscribe(
    (routeData: any) => {
      this.routeData = routeData;
      this.start();
    },
    (error: any) => {
      console.log('Error: ', error);
    }
  );
}

Edit2: Current Approach (routeObservables lacks reusability in other components)

 getAllRouteData() {
    const routeObservables = [
      this.route.paramMap.pipe(map(() => window.history.state)),
      this.route.url,
      this.route.params,
      this.route.queryParams,
      this.route.fragment,
      this.route.data
    ];

    forkJoin(routeObservables.map(r => r.pipe(first()))).subscribe(
      (routeData: any) => {
        this.routeData = routeData;
      }
    );
  }

Reason for Inquiry:

My key challenge lies in maintaining "single responsibility"; I strive to evade duplication of code (e.g., routeObservables above in each component requiring route-related data).

Answer №1

It seems like the issue at hand involves working with string values and converting them to Javascript objects. To accomplish this, you can access these properties using square brackets:

const keys = Object.keys(this.RouteObservables);
const sources = this.keys.map(key => this[this.RouteObservables.key]);

forkJoin(...this.sources).subscribe(
  (routeData: any) => {
    this.routeData = routeData;
  }
);

Additionally, remember to have this.route injected in the class constructor.

While I haven't tested this solution, I believe it should resolve the issue. Let me know if you encounter any errors.

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

Having multiple template bindings on a single element is not possible. Please utilize only one attribute with the prefix "*" for </mat-header-cell>

I encountered the following error: ERROR in Can't have multiple template bindings on one element. Use only one attribute prefixed with * (" <mat-header-cell> <mat-cell *matCellDef="let order" class="{{orderColum ...

Refreshing MongoDB data by utilizing values from an object

I am facing a challenge with my MongoDB collection structure: [ { "stock": "GOOGLE", "price": 0 }, { "stock": "FACEBOOK", "price": 0 } ] On the other hand, I have a Stock_P ...

Options are not being shown in the Mat-Select

I am currently working on an Angular application and encountering an issue with displaying options. When the page loads, the options are missing, and there is no error being thrown (nothing in the console). I even attempted a simpler version without connec ...

What is the best method to find a matching property in one array from another?

I am working with two arrays in TypeScript. The first one is a products array containing objects with product names and IDs, like this: const products = [ { product: 'prod_aaa', name: 'Starter' }, { product: 'prod_bbb&apos ...

When utilizing the file-loader in Webpack with a function in the outputPath parameter, an EISDIR error occurs,

I am attempting to create a specific output format for my locale files in the form of _locales/[locale_shortcut]/[file].json To achieve this, I am utilizing the file-loader plugin within webpack. While the documentation mentions the use of a function with ...

Why is the dateclick event in PrimeNG's FullCalendar not being emitted when clicking on a date? What is the best way to handle click events on specific dates within the calendar?

I am new to using Angular and PrimeNG, and I am facing challenges while trying to implement the FullCalendar component. The specific component I am referring to can be found here: The issue arises when I attempt to trigger an event when a user clicks on a ...

Having trouble retrieving the default selected value using the index in Angular Material's mat-button-toggle functionality

I'm encountering an issue with setting the default value for a toggle button group. The code is simple and the toggle buttons are correctly fetching values from the index, but I can't seem to get one of them to be default selected. I tried settin ...

What is the process of bringing in a Svelte component into a Typescript file?

Can a Svelte component be imported into a Typescript file and successfully compiled by Rollup? While the following code works fine as a Javascript file, it encounters errors when converted to Typescript, as the TS compiler struggles with a .svelte file: i ...

What steps should I take to choose esNext from the typescript menu within visual studio 2017?

When utilizing dynamic import with TypeScript in Visual Studio 2017, I encountered the following error: TS1323(TS) Dynamic imports are only supported when the '--module' flag is set to 'commonjs' or 'esNext'. I attempted to c ...

Encountered an error trying to access '0' property of an undefined object when iterating through data in angular framework

My API is returning data in the format shown below: "fileName": "data.txt", "onlyInFile1": [ { "_id": "60618e87c2077428e4fedde5", "TERMINAL_ID": "Y6152114", "EXTERNAL_STAN": & ...

What is the way to send custom properties to TypeScript in combination with StyledComponents?

Encountering an error while attempting to implement Styled Components 3 with TypeScript: TS2365: Operator '<' cannot be applied to types 'ThemedStyledFunction<{}, any, DetailedHTMLProps<TableHTMLAttributes<HTMLTableElement>, ...

Issues with Angular route links not functioning correctly when using an Array of objects

After hard coding some routerLinks into my application and witnessing smooth functionality, I decided to explore a different approach: View: <ul class="list navbar-nav"></ul> Ts.file public links = [ { name: "Home&quo ...

The error message "Property 'list' is not found on type 'void' React - Material UI" indicates that the 'list' property is not recognized

Currently, I am facing an issue while working with Material UI and React Typescript. The error message I receive is "Property 'list' does not exist on type 'void'" when attempting to use makeStyles and createStyles to remove padding. It ...

What is the best way to display suggested words from a given list of options?

Looking for a way to provide suggestions to users based on a list of words they enter in TypeScript while maintaining performance. How can this be achieved efficiently? ...

Importing Angular Material modules

I've integrated the Angular Material module into my project by updating the material.module.ts file with the following imports: import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { MatT ...

Create an array of arrays within a loop using TypeScript

My application contains an object with dates and corresponding time arrays. The console log output is displayed below: 32: { 1514160000: Array [ 1200, 1500 ], 1514764800: Array [ 1200, 1500 ], 1515369600: Array [ 1200, 1500 ], 1515974400: Array [ 700, 12 ...

How come TypeScript doesn't recognize my MongoDB ObjectID as a valid type?

Currently, I am working with Node.js, MongoDB, and TypeScript. The code snippet below is error-free: const ObjectID = require("mongodb").ObjectID; const id = new ObjectID("5b681f5b61020f2d8ad4768d"); However, upon modifying the second line as follows: ...

Implementing a NextJS client component within a webpage

I am currently working with NextJS version 14 and I am in the process of creating a landing page. In one of the sections, I need to utilize the useState hook. I have specified my component as "use-client" but I am still encountering an error stating that " ...

Generate a collection of elements using a different collection as a reference

I am struggling with an array of objects: let data = [{ createdDate: "2222", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="087c6d7b7c3d487c6d7b7c266b6765">[email protected]</a>", histories: [ ...

An issue occurred during the project compilation using npm

My project installation process is giving me some trouble. Initially, when I run npm install, it successfully installs all the dependencies. However, when I proceed to execute npm run compile, I encounter an error. Below is the log file for a better under ...