Integrate data flow from ActivatedRoute observables with Observables generated from API requests

Seeking to combine two observables using either forkJoin or combineLatest (my current options). One observable originates from the ActivatedRoute's data (Observable<Data>) and the other is a call to the API (Observable<Project>). https://i.sstatic.net/fu45O.png

Originally, these two were nested and functioning correctly. However, I believe that combining the observables may lead to improvement. I acknowledge that the observable from the activated route is ongoing and is invoked each time the user navigates within the app. The second observable concludes upon receiving a response. forkJoin operates with completed observables while combineLatest handles ongoing ones, capturing their latest values.

Is there a way to amalgamate these two, or is the nested approach the optimal solution? Appreciate your insights!

EDIT: Made some minor corrections and introduced array deconstruction to the code.

On a side note, I encountered an issue where upon refreshing the app on the current page, the routeData appears as an empty object. However, placing a breakpoint where the routeData is defined resolves the issue. It seems as though a slight delay is required for the current routeData to be populated. Why isn't it automatically triggered once the data is added to the route? Apologies if this is confusing

Further update: I have two pages with their respective components: Asset Management (AssetManagementComponent) and Projects Management (ProjectManagementComponent). The Project component is a subcomponent of the Asset component. Upon initializing the asset component, I fetch data from the API and assign it to route.data. Subsequently, when the project component (child) is loaded, I aim to retrieve the route data along with additional project-specific data from the API.

The issue arises when I refresh the Project Management page, resulting in routeData being an empty object {} based on the above code. However, if I navigate from Asset Management to Project Management, routeData contains the accurate data.

In an attempt to debug this problem using DevTools, I noticed that placing breakpoints in each ngOnInit() function results in the correct routeData, even when directly refreshing the app on ProjectManagement.

UPDATE:

Here is the final and functional version: https://i.sstatic.net/e0PZZ.png The issue was resolved by adding a filter to the route data observable, ensuring that it first triggers with an empty object and then with a valid object.

Many thanks to all for your valuable input, I have gained new insights and best practices! Wishing you a wonderful day!

Answer №1

It seems like the best approach for this situation would be to utilize the mergeMap function. From what I gather, the issue arises when the activeRoute subscriptions are initially empty upon refresh, but then receive data and trigger a second subscription.

This method involves filtering out route params that do not contain an asset, and then using mergeMap to pass it along to the next request. This ensures that both values are always present once the code reaches its final destination.

A revised version of the code could look something like this:

this.route.parent.data.pipe(
  filter(routeData => routeData && routeData.asset), // making sure route data exists
  mergeMap(routeData =>{
    return this.projectService.getProjectDetails(projectId).pipe.map(project =>{
       return {routeData, project}
    })
  }),
  map(data => {
    // Now you should have access to both data.routeData and data.project
     
  })
).subscribe()

I hope this solution proves helpful, as dealing with routeParams can be quite tricky when they are needed to make additional calls. I believe the code provided is accurate, but please excuse any errors as it's a late night and I'm relying on memory (and Google) for assistance. haha

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

Is there a method to obtain the compiled CSS for an Angular 2+ component?

Is it possible to retrieve compiled CSS (as a string) from an Angular2+ component? @Component({ selector: 'test-graph', templateUrl: './test-graph.component.html', styleUrls: ['./test-graph.component.scss'] }) export cla ...

When the value is empty, MUI Autocomplete will highlight all items

I have encountered a specific issue. I am working on developing a custom Autocomplete Component for filtering purposes. However, I recently came across the following Warning. MUI: The value provided to Autocomplete is invalid. None of the options matc ...

Identifying whether an Angular component has been loaded through a template or a route: Ways to distinguish

How can I determine how an Angular component was loaded? I have a component that can be accessed through a route or loaded within another component's template, and I want to be able to identify the loading method for the purpose of animations. ...

The error message "Property 'hideKeyboardAccessoryBar' does not exist on type 'Keyboard'." appeared while using the IONIC Moodle App

Having an issue in the IONIC Moodle App with a typescript error stating that property 'hideKeyboardAccessoryBar' does not exist on type 'Keyboard'. An ionic error occurred when running CMD, displaying the following error: [14:58:02] ...

Guidance on converting a file object to a blob/byte array within a TypeScript interface

I'm facing an issue where the file input field is not properly uploading the file into an Angular object to be sent to an API. When I check the file, it appears empty like {}. This results in the server-side response showing an empty object as well: { ...

There seems to be an issue with the subscription of a subject between two modules in Angular 5

Currently, I am in the process of developing a project using Angular 5. One requirement is to display an app loading spinner frequently. To achieve this, I have created a shared module along with a spinner component within it. Below is the content of my mo ...

Expired URL in Ionic 3 Navigation

I'm a novice at using Ionic. I recently started my first project about a month ago and it's nearing completion. However, I noticed that whenever I run ionic serve, my app always defaults to localhost:8100. For example, when I land on the home pa ...

An error is anticipated when () is added, but surprisingly, I still encounter an error as well. This issue arises in React-Native and Typescript

I am still relatively new to React-Native, but I have been using React-Native, TypeScript, and integrating it with Firebase. An unusual error has occurred, which is visible in the screenshot below. However, when checking in VSC, the error seems to be non-e ...

In this guide, we will explore the process of designing unique styles for ng

What is the proper way to customize CSS for a specific element? &.ng-select-focused { &:not(.ng-select-opened) > .ng-select-container { border-color: $ng-select-highlight; box-shadow: $ng-select-box-shadow; } } The offi ...

Encountering obstacles when attempting to initiate a node application due to an error

Upon starting my node application, I encountered an error. The error message reads: "ERROR in Metadata version mismatch for module ../node_modules/@ng-bootstrap/ng-bootstrap/index.d.ts, found version 4, expected 3" Here is the full error trace: ERROR ...

Learn the steps to designing a responsive class using Angular2's ngClass feature

Imagine a scenario where the object models in my cloud Array include a weight key: return [ { term: '1994', weight: 0 }, { term: '2017', weight: 0 }, { term: '89th', ...

Closing iframe in Angular 4 after redirection

I am currently working on an Angular 4 application that involves integrating a third-party payment system called Tranzila. Tranzila offers a convenient integration method using an iframe, allowing users to make payments on their domain without me having to ...

Wrapping an anonymous function in a wrapper function in Typescript can prevent the inferred typing

I am encountering an issue with typing while coding: function identity<T>(v: T): T{ return v; } function execute(fn: {(n: number):string}) {} execute((n) => { // type of n is 'number' return n.toFixed(); }) execute(identity(( ...

Scrolling through a list in Angular using cdk-virtual-scroll-viewport while selecting items via keyboard input

Looking to implement a customized Autocomplete feature. As the user begins typing, a small window should appear with selectable options. I want users to have the ability to navigate and select an option using their keyboard. For instance: - User types "H ...

Adding a declaration file to a package that relies on an external declaration file can be achieved by following these

In the process of developing a library that relies on another package lacking a declaration file in its npm package, I have successfully installed the necessary declaration file with typings. Everything seems to be working well. Yet, the question remains: ...

Transmit a sequence of keys to the web browser

I'm having difficulty in sending a Shift key command followed immediately by tilde (~). I've attempted various examples, and here's one that I'm currently working on. I am testing the following scenario - selecting a specific image, t ...

Resolve the issue of text overflow in PrimeNG Turbo Table cells

When utilizing Primeng table and enabling the scrollable feature, the table is expected to display a scrollbar while ensuring that the text within the cells does not overflow. Unfortunately, this expected behavior is not occurring. To see an example of th ...

Enhance the Nuxt 3 experience by expanding the functionality of the NuxtApp type with

When I include a plugin in my NuxtApp, it correctly identifies its type. https://i.stack.imgur.com/UFqZW.png However, when I attempt to use the plugin on a page, it only displays the type as "any." https://i.stack.imgur.com/hVSzA.png Is there a way for ...

Deleting an element in an Array of objects using Typescript

export class AppComponent implements OnInit { title = 'bucketList'; bucketList: BucketListItem[] = [ new BucketListItem( "Goa Trip", "Travel to Goa" ) ]; ngOnInit() { } onItemAdded(eventData) ...

Is it possible to define TypeScript interfaces in a separate file and utilize them without the need for importing?

Currently, I find myself either declaring interfaces directly where I use them or importing them like import {ISomeInterface} from './somePlace'. Is there a way to centralize interface declarations in files like something.interface.ts and use the ...