Search code examples
angularngxs

NGXS - set property within object


I am trying to put my site configuration as an object within NGXS. Rather than creating an action to set the value for each property of the object - I wanted to allow a single action to contain the property name and new value. I would then update that property. I have tried a few ways but none seem to work....

import { State, Action, Selector, StateContext } from '@ngxs/store';
import { SetLayout, SetTheme, SetLayoutConfigurationProperty } from './layout.actions';
import { Injectable } from '@angular/core';
import { LayoutConfiguration } from './layout.types';

export interface LayoutStateModel {
  currentTheme: string;
  configuration: LayoutConfiguration;
}

@State<LayoutStateModel>({
  name: 'layout',
  defaults: {
    currentTheme: 'light',
    configuration: {
      ShowAvatar: true,
      ShowMessages: true,
      ShowSearch: true,
      ShowShortcuts: true,
      ShowSidebarAlerts: true,
      ShowSidebarUserMenu: true,
    },
  },
})
@Injectable()
export class LayoutStateModule {
  @Selector()
  public static getCurrentTheme(state: LayoutStateModel): string {
    return state.currentTheme;
  }
  @Selector()
  public static GetConfiguration(state: LayoutStateModel): LayoutConfiguration {
    return state.configuration;
  }

  @Action(SetTheme)
  public SetTheme({ patchState }: StateContext<LayoutStateModel>, { payload }: SetTheme): void {
    patchState({ currentTheme: payload });
  }
  @Action(SetLayoutConfigurationProperty)
  public SetLayoutConfigurationProperty(
    { getState, patchState }: StateContext<LayoutStateModel>,
    { payload }: SetLayoutConfigurationProperty
  ): void {
    patchState({ configuration: { ...getState().configuration, [payload.property]: payload.value } });
  }
}

With the action being (Am sure you don't need this code)

export class SetLayoutConfigurationProperty {
  public static readonly type = '[Layout] Set confiuration property change';
  constructor(public payload: { property: string; value: boolean }) {}
}

But triggering the action SetLayoutConfigurationProperty seems to cause an infinite loop. Any help would be appreciated


Solution

  • This looks fine to me, is it an infinite loop of SetLayoutConfigurationProperty actions being dispatched?

    Do you have anything that subscribed to this part of the state and dispatches an action when it changes?

    It seems likely that this would cause this kind of issue. To debug I would set a break point in the action constructor to see where it is being dispatched and why