The withLatestFrom operator will not trigger with a null value

Working on an Angular project that utilizes @ngrx/effect, we are incorporating an observable stream with the withLatestFrom rxjs operator.

Here is a glimpse of our observable effect stream:

@Effect()
handleUsersData$ = this.actions$
.pipe(
    ofType(HANDLE_USER_DATA),
    withLatestFrom(
      this.store.pipe(select(getCurrentUserId)),
      this.store.pipe(select(getUserEntities)),
    ),
    tap(([action, currentUserId, users]) => console.log(([action, currentUserId, users]))),
    switchMap(([action, currentUserId, users]) => {
      const dispatchedActions: Action[] = [];

      if (currentUserId) {
        dispatchedActions.push(new SetCurrentUser()); 
      } else {
        dispatchedActions.push(new SomeAction());
        dispatchedActions.push(new ClearUsers());
      }

      return dispatchedActions;
    })
);

One of the selectors being used is as follows:

export const getCurrentUserId = createSelector(
  getUserEntities,
  getRouterStateUrl,
  (users: Dictionary<User>, router: RouterStateUrl) => {

    return router.params && users[router.params.userId] || null;
  }
);

When a userId is specified, the actions are correctly dispatched. The user ID and user entities are displayed in the console.log.

However, when the userId is not included in the router params, the selector returns null and the observable stream does not trigger. The console.log within the tap function shows nothing.

Why does the withLatestFrom appear to disregard the null value and fail to tick if this is the outcome of the selector? This value is valid within our scenario.

What can be done to guarantee that the observable stream keeps ticking even when there is a null value in the getCurrentUserId selector?

Answer №1

If you're considering using combineLatest, it may be a better option in this case.

The difference with withLatestFrom is that it doesn't ignore null. It actually treats it as a regular value. Additionally, withLatestFrom only reacts to emissions from its direct source, which in this scenario is

this.actions$.pipe(ofType(HANDLE_USER_DATA))
. Any emissions from other sources are kept in its internal buffer without triggering a reaction.

In contrast, combineLatest will emit every time there is an emission from any of the source Observables, but only after each one has emitted at least one item (consider using startWith if you want to ensure all sources emit at least once).

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

How come the type declaration ( () => string ) suddenly pops up?

I am currently utilizing the jasonwebtoken package and have encountered a new javascript/typescript behavior. interface JwtPayload { [key: string]: any; iss?: string | undefined; sub?: string | undefined; aud?: string | string[] | undefined ...

Angular displays X items in each row and column

I've been struggling with this task for the past 2 hours. My goal is to display a set of buttons on the screen, but I'm facing some challenges. The current layout of the buttons doesn't look quite right as they appear cluttered and unevenly ...

The offsetWidth of the nativeElement in Angular 2's ElementRef is consistently returning a value

Is there a way to retrieve the width of an element with a dynamic width using Angular 2? I can easily accomplish this with pure javascript, but not through Angular 2. constructor(private element: ElementRef) { // .... Obtaining the width let width = thi ...

Fix a typing issue with TypeScript on a coding assistant

I'm struggling with typing a helper function. I need to replace null values in an object with empty strings while preserving the key-value relationships in typescript // from { name: string | undefined url: string | null | undefined icon: ...

Automatically reloading clients after deployment with Angular 10 for enhanced user experience

As of now, my application is live with all the JavaScript files having a timestamp version. However, when I rebuild my Angular app, the JavaScript files will be updated with a new timestamp version. https://i.stack.imgur.com/M8MDN.png Is there a method t ...

Assigning union values to an object array: a guide for Typescript

When working with union typed values in an object array, how should the setState() function be implemented? enum SomeStateEnum { IsRunning, Name, } type PersonState = { [SomeStateEnum.IsRunning]: boolean; [SomeStateEnum.Name]: string; }; const st ...

Maximizing the potential of process.hrtime.bigint

Whenever I include the following code: const a = process.hrtime.bigint(); The linter says it's okay, but during compilation, I encounter this error message: error TS2339: Property 'bigint' does not exist on type 'HRTime'. This ...

Calculating numbers with Math.ceil will result in an increase of 1

After using Math.ceil, one value was rounded up to 50 and the other to 80. However, when I added these two values together, the result unexpectedly turned out to be 131. console.log(Math.ceil(e.currentTarget.clientHeight) // 50 console.log(Math.ceil(e.cu ...

Incorporating a script into Angular can only be done within the index.html file

Currently, I am faced with an issue while working with Angular 17. I am attempting to utilize a script for generating a form within a component. The script can be found at this source: https://sandbox.przelewy24.pl/inchtml/ajaxPayment/ajax.js?token={TOKEN} ...

Why is Axios not being successfully registered as a global variable in this particular Vue application?

Recently, I have been delving into building a Single Page Application using Vue 3, TypeScript, and tapping into The Movie Database (TMDB) API. One of the hurdles I faced was managing Axios instances across multiple components. Initially, I imported Axios ...

Utilizing Express-sessions to generate a fresh session with each new request

I'm facing an issue with my express backend using express-sessions and Angular frontend. Every time the frontend makes a request, a new session is created by express-sessions. I suspect the problem lies in Angular not sending the cookie back, as I don ...

Error Alert: Next.js TypeScript is reporting that the necessary packages are missing from your setup

As I work on developing a basic Next.js website using their TypeScript starter, everything was going smoothly with the 'yarn dev' command. However, out of nowhere, I started encountering an error message whenever I tried to run 'yarn dev&apo ...

Vue - Troubleshooting why components are not re-rendering after data updates with a method

Check out this simple vue component I created: <template> <div class="incrementor"> <p v-text="counter"></p> <button v-on:click="increment()">Increment</button> </div> </template> <script lan ...

Showing Bootstrap Style with Angular's NgFor and NgStyle

I'm currently working on displaying a header nav menu using a typescript object array with Bootstrap. The problem I'm facing is that the menu displays vertically instead of horizontally when using the array. I suspect it has something to do with ...

Exploring the world of Angular CLI testing and the versatility of

Struggling with integrating Angular CLI's test framework and enum types? When creating an enum like the following (found in someenum.ts): const enum SomeEnum { Val0, Val1 } Utilizing it in this way (in app.component.ts): private someEnum = Some ...

Creating TypeScript atom packages

Has anyone successfully implemented this before? I couldn't locate any assistance for it. If someone could provide references to documentation or existing code, that would be great. I know that Atom runs on Node and that there is a TypeScript compil ...

Building a TypeScript Rest API with efficient routing, controllers, and classes for seamless management

I have been working on transitioning a Node project to TypeScript using Express and CoreModel. In my original setup, the structure looked like this: to manage users accountRouter <- accountController <- User (Class) <- CoreModel (parent Class o ...

Issue encountered in Angular 4 due to XSS script in URL causing "Cannot match any routes" error

I've been working on a project in Angular 4 and encountered an issue while setting up routes for a feature module. The error message I'm receiving is Error: Cannot match any routes. Below is the code snippet of the routes I've defined: con ...

Angular Recursive Bootstrap Breadcrumb Guide

I am looking to implement the bootstrap breadcrumb component (https://getbootstrap.com/docs/4.0/components/breadcrumb/) in my project. My goal is to use the breadcrumb to show the entire path to the current directory within a component that resembles a di ...

Handling a change event for a mat-datepicker in Angular 7 can be tricky, especially when its value is tied to an optional input parameter. Let's dive into how to

I've recently started working with angular development and encountered a challenge with a mat-datepicker. The value of the datepicker is connected to filterDate using [(ngModel)] as an @Input() parameter. I have implemented a handleChange event that e ...