Search code examples
typescriptngrx

TypeError: "value" is read-only


I'm trying to send data to my backend with ngrx store but i'm getting this error: ERROR TypeError: "value" is read-only. I tried a lot of things but no one worked.

I have to send the "equipment" object which contains an array of properties which has just been modified, the equipment in question is registered in the store, I get it directly from the store in the component to make my form

my code on the effect:

updateEquipment$ = createEffect(() =>
    this.actions$.pipe(
      ofType(SettingsActions.updateEquipment),
      switchMap(action => {
        const equipment = { ...action.equipment };
        // const result = { ...action.gasxProperty };
        action.gasxProperty.forEach(res => {
          equipment.properties.find(prop => prop.name === res.name).value = res.value; // <== here i get the error
        });
        return this.settingsService.saveEquipment(action.equipment).pipe(
          map(equipmentSaved => {
            this.store.dispatch(CoreActions.hideSpinner());
            this.toastrService.success('', 'Equipement sauvegardée.');
            return SettingsActions.updateEquipmentSuccess({ equipment: equipmentSaved });
          }),
          catchError(() => {
            this.store.dispatch(CoreActions.hideSpinner());
            this.toastrService.error('', 'Erreur de sauvegarde.');
            return of(SettingsActions.updateEquipmentError());
          })
        );
      })
    )
  );

On my component, i do this to save:

public equipment$: Observable<Equipment>;

constructor() {
    this.equipment$ = this.store.select(fromSettings.getSelectedEquipment);
  }

        public onSubmit(equipment: Equipment): void {
          const result = Object.keys(this.form.controls.gasx.value).map(key => ({
            name: key,
            value: this.form.controls.gasx.value[key]
          }));
          result.pop();
          this.store.dispatch(CoreActions.showSpinner());
          this.store.dispatch(SettingsActions.updateEquipment({ equipment, gasxProperty: result }));
      }

the html:

<ng-container *ngIf="(equipment$ | async) as equipment">
      <div *ngIf="!isEditable"
        (click)="turnOnCheckbox(equipment)"
        class="flex items-center justify-center w-8 h-8 rounded-full bg-smg-lightGray">
        <img class="w-3 cursor-pointer"
          src="../../../../../../assets/icons/pen.svg" />
      </div>
    </ng-container>

and the action was:

export const updateEquipment = createAction(
  '[Settings] Update equipment',
  props<{ equipment: Equipment; gasxProperty }>()
);

Any ideas?


Solution

  • You can't do this because the action is "frozen" (read-only).

    action.gasxProperty.forEach(res => {
      equipment.properties.find(prop => prop.name === res.name).value = res.value; // <== here i get the error
    });
    

    Instead, you should update it in a immutable way (with the spread syntax)