Stopping Duplicate Actions in Redux with Angular

I find Redux to be a very impressive library, and I am quite fond of it. However, I am facing an issue where actions are being called twice. What are some common mistakes that could be causing this behavior? Please note that I have already unsubscribed the subscription in the controller.

constructor(private _store: Store<AppState>) {
    this.subscription = this._store.select('reduxObj').subscribe(function (item) {
      switch (item.type) {
        case fromAction.GETITEMS: {
          break;
        }
      }
    }.bind(this));
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }


  ngOnInit() {
    this._store.dispatch(new fromAction.GetListAction());
  }



    //REDUCER
    export function ReduxReducer(state: any = undefined, action: fromAction.actions) {

  switch (action.type) {
    case fromAction.GETITEMS: {
      return { ...state, type: fromAction.GETITEMS }
    }
  }


  //ACTION
  export class GetListAction implements Action {
    readonly type = GETITEMS;
    constructor() { }
  }

Answer №1

It's interesting how people tend to focus on insignificant details.

Let me give you a direct answer to your question:

In a basic scenario, a select function on a store is designed to listen to dispatch events.

If you call dispatch twice, your subscription will be triggered twice as well.

Unless there are additional effects involved, the behavior remains simple and straightforward.

The reason for the double invocation is usually linked to the default value set when instantiating the store.

(state: MyState, action: MyAction implements Action) => any

In most cases, it is structured like this:

myReducer(state: MyState = undefined, action: MyAction implements Action) { ... }

This setup implies that the initial state is undefined, and triggering dispatch changes it to a defined state.

Hence, the repeated calls.

On a side note, relocating this logic to the constructor won't alter the outcome.

EDIT

To avoid processing the initial value, consider using either filter or skip (choose based on your requirement):

this.subscription = this._store.select('reduxObj').pipe(
  // For an array, skip empty arrays
  filter(value => value.length),
  // For `undefined`, skip falsy values
  filter(value => !!value),
  // Skip the first emitted value
  skip(1),
)

Answer №2

First and foremost, there is no need to use .bind(this) in observer functions. Additionally, you can make use of ES6 arrow functions instead of traditional JavaScript functions as callbacks (() => {}).

Regarding your query, the optimal approach to retrieving only a single value from an Observable is by including the take() method in the RxJS pipeline, like so:

         this.subscription = this._store.select('reduxObj')
           .pipe(take(1))
           .subscribe((item) => {
              switch (item.type) {    
                case fromAction.GETITEMS:{                                                                                                        
                  //...                                    
                  break;
                }
              }
        }); 

In order to implement this, you need to import take from 'rxjs/operators' if you are using RxJS version 5.5 or above.

import { take } from 'rxjs/operators';

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

I am puzzled as to why I am receiving the error messages stating that [ngForm] is not recognized as a valid property for the form element, and that [ngClass] is not a recognized

I've been working on this code in Angular 14 for a large client project. The standard imports are listed below, along with a snippet of the .html page: import { Component, OnInit, ViewChild } from "@angular/core"; import { FormBuilder, FormC ...

What are the possibilities for adjusting the tooltip position in ng2-chart?

I am currently working on creating a Doughnut Chart using ng2-chart Angular2 directives for Chart.js. The default setting for the tooltip positioning in Chart.js is inside the chart, but I would like to customize it to display outside of the chart area. Is ...

Using Vue.js - error occurs when trying to push an object using the push method

I encountered an issue while trying to use the push() method to add data to an object: Uncaught (in promise) TypeError: this.message.push is not a function The scenario involves receiving data from an API call and needing to append it to an object. var ...

Finding the data type of a collection of functions stored in an associative array

I am seeking assistance in creating a function where the caller must provide an associative array of functions. The function should return a new associative array with the same keys and return types, but each function will take a different argument compare ...

Exploring Real-Time Typescript Validation in Next.JS

Checking for TypeScript errors in Next.JS can only be done with npm run build (or yarn build). Unfortunately, running npm run dev won't display TypeScript errors, which is quite inconvenient as it would be better to have them visible in the Terminal ...

Struggling to understand how to implement Schema Directives after transitioning to Typescript

After spending several days rewriting my GraphQL server to Typescript, I found myself struggling with defining Schema Directives. Despite extensive googling, I could not find any examples of using "more advanced" Apollo GraphQL with Typescript. Everything ...

Is there a way to transfer the node_module folder to a different drive using npm without duplicating the API multiple times?

I have come across a problem in my workspace where Node projects are utilizing various version dependencies, resulting in duplicate copies of the same node module. This has made it extremely difficult to locate my files and is causing excessive storage c ...

utilizing type predictors in brand merging

For hours now, I've been struggling with a small problem that seems to have no solution in sight. I wonder if someone with a sharper mind could offer me some guidance? The method I'm using returns a predicate: this is xxx. This method is then us ...

Encountering an Uncaught ReferenceError in Angular 8 and Webpack 4: Issue with vendor_lib not being defined plus source map error

Recently, I started working on a relatively simple interface that was initially developed in Angular2. As someone new to Angular2 and webpack, there were some challenges. I successfully upgraded the project from Angular 2.4 to Angular 8.0. Additionally, ...

Blocks visible when tabs are switched

Seeking advice on how to dynamically switch content within tabs without affecting the header that remains constant across all tabs. I currently have a panel with tabs and a container for content. The goal is to use the selectedTabChange event listener to d ...

Angular Universal's SSR causing a double page load event

Within my main code (app.component.html), there are no higher level NgIf statements that would trigger a reload. To prevent requests from being called after SSR sets the answers of public URLs, I am utilizing transferstate. I am also using isPlatFormBrows ...

Troubleshooting problem with Angular 2 integration in asp.net core involving controller and action names resulting in main.js file not being located

My angular 2 application is successfully set up in asp.net core and everything is working perfectly. The main.js file is located inside the app folder. Everything is running smoothly because of the default MVC template used. app.UseMvc(routes => ...

The variable in my NodeJS code is persisting across multiple requests and not being reset as expected

After setting up a project with the help of Typescript-Node-Starter, I have successfully created a controller and a route to call a specific function. import { Request, Response } from "express"; import axios from "axios"; import { pars ...

The bar graph dataset is not correctly configured when utilizing ng2 charts and ng5-slider within an Angular framework

Currently, I am working with a range slider and bar graph. My goal is to dynamically change the color of the bar graph using the range slider. While I have managed to successfully alter the color of the bars, I am facing an issue where the data displayed ...

One particular module is causing disruption to the hot module replacement functionality across my entire application

My experience with hot.accept at the root of my application has been very successful so far. var hot = (<any>module).hot; if (hot) { hot.accept(); } But ever since I upgraded to Angular 2 RC5 and started using their module system, I've enc ...

The functionality of `import { Dialogs } from "@nativescript/core"; seems to be malfunctioning

For my project, I am in need of using Dialogs. Unfortunately, the import from @nativescript/core as mentioned in their documentation is not working. I keep encountering this error: Module '"@nativescript/core"' has no exported member &a ...

ES5 approach to Angular2 HTTP Providers (not TypeScript)

I'm currently developing an application and experimenting with Angular2 using ES5 JavaScript for fun. My main inquiry right now is how to access the Http service. Most of the available documentation is in TypeScript, which is not very helpful, or it p ...

Is it compatible to use Typescript version 2.4.2 with Ionic version 3.8.0?

Is it compatible to use Typescript 2.4.2 with Ionic 3.8.0? $ ionic info cli packages: (C:***\AppData\Roaming\npm\node_modules) @ionic/cli-utils : 1.18.0 ionic (Ionic CLI) : 3.18.0 global packages: cordova (Cordova CLI) : not insta ...

Error encountered in Angular while using CKEditor: Trying to read the property 'type' of a null value results in a TypeError after inserting text

I'm currently developing an application that utilizes CKEditor within the Angular framework. Everything seems to be functioning as expected, except for when I attempt to execute the insertText function, it triggers the following error: edit.html:180 ...

Obtain the Angular 2 Form object within a TypeScript class file for manual configuration of form properties

I have a form inside a PrimeNG dialog control. I need to handle two different submit methods based on certain conditions for this form, so I don't want to use the ngSubmit method in the form tag. Instead, I want to manually access the form object in m ...