Uncertainty surrounding the combination of observables due to their varying outcomes

Currently, I am developing an angular2 application that implements the ngrx store approach for state management. The source code for the app is available on github here

The Issue at Hand

The specific challenge I am encountering with this method involves handling values emitted from one observable in cases where another observable returns null.

I prefer not to query the backend API if the required data is already present in my ngrx store.


Angular2 Code

Here is an excerpt from my trips.reducer.ts file

export interface State {
  ids: string[];
  trips: { [id: string]: Trip };
  selectedTripId: string;
}

const initialState = {
  ids: [],
  trips: {},
  selectedTripId: null
}

export function reducer(state = initialState, action: Action ): State {}

export function getTrips(state : State) {
  return state.trips;
} 

export function getTripIds(state: State) {
  return state.ids;
}

export function getSelectedTripId(state: State) {
  return state.selectedTripId;
}

And here is a snippet from my base reducer index.ts

export interface State {
  trips: fromTripsReducer.State;    
} 

const reducers = {
  trips: fromTripsReducer.reducer,
}

//Other selector functions and mappings...

Now, within my trip-detail.component.ts, I can access a particular trip like this

selectedTrip$: Trip;

constructor(private store: Store<fromRoot.State>) {
  this.selectedTrip$ = this.store.select(fromRoot.getSelectedTrip);
}

However, upon reloading the route as localhost:4200/trips/2, the store will reset to its initialState which could lead to issues when the expected data is missing.

In such scenarios, it may be necessary to resort to backend requests only if the required trip information is not available in the store and

the selectedTrip$ object returns null or undefined.

this.selectedTrip$ = this.store.select(fromRoot.getSelectedTrip);

Answer №1

If you want the data to be available before displaying the component, utilizing a resolver would be beneficial. You can refer to this helpful answer here.

In your specific scenario, the implementation would ensure that the data loading starts only if selectedTrip is null. It's important to note that since the resolved data won't be used elsewhere, any value can be returned.

@Injectable()
export class SelectedTripResolver implements Resolve {

constructor(
    private store: Store
) {}

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {

    // Accessing the selectedTrip
    return this.store.select(fromRoot.getSelectedTrip)
        .map( (selectedTrip) => {
            if (selectedTrip === null) {
                // Trigger actions to load trips & selectedTrip
                this.store.dispatch(new LoadTripAction());
                this.store.dispatch(new LoadselectedTripAction());
                return false; // Return any value
            } else {
                return true; // Return any value
            }
        });

}

The resolver ensures that the loading actions are initiated when the selectedTrip data is not yet available.

In the trip-detail.component, you simply need to wait for valid data as shown below:

constructor(private store: Store<fromRoot.State>) {
    this.selectedTrip$ = this.store.select(fromRoot.getSelectedTrip)
        .filter(selectedTrip => selectedTrip !== null);
}

I hope this explanation clarifies things and assists you in your implementation.

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

Various modules in the project need to have distinct GitHub origins, particularly in the case of Spring-Angular

My goal is to create a well-structured project with separate frontend and backend modules. Here is the initial project structure: https://i.stack.imgur.com/EghPA.png I have attempted this in various configurations before, but every time I try, git recogn ...

Creating a declaration file for a library's entry point involves outlining the structure and types

I have developed an npm library that is made up of several ES6 modules, which are then consolidated into a single js file. The directory structure looks like this: src main.ts one.ts two.ts three.ts types index.d.ts index.ts The index.ts fil ...

The Angular2 Router directs the user to the main Component

After configuring the Angular2 router and setting up the server (asp.net core) to redirect unknown paths to /index.html, the routing appears to be functioning properly. However, I am encountering an issue where visiting a specific URL (i.e. www.sitename.co ...

What is the best way to assign SnapshotChanges to an Observable Firebase variable?

I'm facing an issue where I can't access the id of a document even though it's visible when printing the object this.ressobj. However, when I try to use ressobj.id_doc in the card, the id of the document is not visible. this.ResColeccion ...

What mechanism allows Angular 2 to identify the parent instance without the need for explicit coding?

Can anyone provide some insight for me please? I have been following this example to create a simple wizard app in Angular 2. Everything is working smoothly, but what confuses me is the constructor in the file called my-wizard-step.ts. How does the private ...

The floating filter in ag-Grid for Angular features a dropdown menu styled with Bootstrap

In my ag-grid table, I have a Bootstrap dropDownMenu displayed in CELL and in FLOATING FILTER. The issue arises when the dropdown menu is triggered - it gets hidden in the cell, as shown in the picture. https://i.sstatic.net/xBsPf.png To fix this proble ...

Show the information stored in an array using Angular

I have recently transitioned from using React to learning Angular, and now I am facing the challenge of displaying data from an array. My goal is to implement a dropdown menu where users can select an ID and see the corresponding address displayed. I bel ...

Can a React-Redux application be built without utilizing combineReducers?

In my app, I am using combineReducers as recommended by the react-redux pack. In my connected component, I have a function: function mapStateToProps(state){ return { listedComments: // a prop name state.allcomments // a reducer name ...

Accurately locate all ChildComponents throughout the entire Component hierarchy

I am facing a challenge in Angular where I need to retrieve all the ChildComponents from my ParentComponent. The issue is that the ChildComponents are not directly nested within the ParentComponent, but instead they are children of other components which a ...

What is the best method to add information into an array using Angular 7?

My data consists of an array of objects : [ { indicatorDatasource: "trackingError", un_an: 0, trois_ans: 0, cinq_ans: 0 }, { indicatorDatasource: "annualisedFundPerformance", un_an: 19.749642029434945, trois ...

Angular2 authguards encountering issues when trying to run asynchronous functions

I need a way to safeguard my routes by verifying if a user is logged in from the server, but I'm facing issues with asynchronous functions not executing properly. Below is the code snippet that's causing trouble: canActivate (route: ActivatedRo ...

Customize the text color of select list options in Angular 5

Is there a way to style the foreground colors of select list options differently in this dropdown code? <select id="tier" class="form-control" [(ngModel)]="tierId"> <option *ngFor="let m of tierList" value="{{m.tier}}" > {{m.option ...

npm-bundle encounters an issue with Error: ENOENT when it cannot find the file or directory specified as 'package.json'

npm-bundle is throwing an error that says Error: ENOENT: no such file or directory, open 'package.json' in my NodeJs project. It works fine if I manually create test.js and package.json, then run npm install followed by npm-bundle. However, when ...

Designing functional components in React with personalized properties utilizing TypeScript and Material-UI

Looking for help on composing MyCustomButton with Button in Material-ui import React from "react"; import { Button, ButtonProps } from "@material-ui/core"; interface MyButtonProps { 'aria-label': string, // Adding aria-label as a required pro ...

Typescript enhances React Native's Pressable component with a pressed property

I'm currently diving into the world of typescript with React, and I've encountered an issue where I can't utilize the pressed prop from Pressable in a React Native app while using typescript. To work around this, I am leveraging styled comp ...

Updating my Angular application using `ng update` did successfully get it to version 11.0.0-next.6. However, I am aiming to revert back

One of my clients has a project using Angular version 8.x.x. I am keen on updating it to the stable version 10.x.x for better performance and features. I followed all the steps mentioned in the Angular update instructions page: https://update.angular.io/? ...

Updating state in Redux from a different componentorModifying state

I'm currently learning about redux and I'm facing an issue with accessing the stored state (id) in my components. Specifically, I have a Footer component with a button that is supposed to modify the state in the Layout component. However, I am un ...

Discovering the intricacies of using *ngFor on an object in Angular with Firebase

Tools I'm Utilizing Angular Firebase My Current Setup A component that showcases information about an 'Issue' Within the issue, there is another section called 'images' Under the image node, there are additional properti ...

Developing OnIdle with rxjs

As I explore rxJS, I've come across this code snippet that monitors browser activity such as mouse movements, clicks, and keyboard usage. It's like the opposite of onIdle. import { fromEvent, throttle, debounce, interval, merge } from 'rxjs& ...

What is the best way to resize a div located below a dynamic div in order to occupy the available space?

My website has a dynamic div1 and a scrollable table inside div2. I need the div2 to take up the remaining height of the window, while ensuring all divs remain responsive. I've tried using JavaScript to calculate and adjust the heights on window loa ...