简体   繁体   中英

Cannot assign to read only property '0' of object '[object Array] primeng

I want to sort the data.table column but, it doesn't work. below is the code and error I get.when I give a server call to backend from typescript it works. When I use state Management the sorting doesn't work.

错误图片

<th *ngFor="let col of columns" [pSortableColumn]="col.field" [ngSwitch]="col.field">
  {{col.header}}
  <p-sortIcon [field]="col.field" ariaLabel="Activate to sort"
  ariaLabelDesc="Activate to sort in descending order" ariaLabelAsc="Activate to sort in ascending order"></p-sortIcon>
</th>

数据源

device.action

  export class LoadDeviceFail implements Action {
    readonly type = DeviceMgtActionTypes.LOAD_DEVICE_FAIL;
    constructor(public payload: string) { }
}
export class LoadDevices implements Action {
    readonly type = DeviceMgtActionTypes.LOAD_DEVICES;
    constructor() { }
}
export class LoadDevicesSuccess implements Action {
    readonly type = DeviceMgtActionTypes.LOAD_DEVICES_SUCCESS;
    constructor(public payload: DeviceModel[]) { }
}

device.effect

 @Effect()
  loadDevices$ = this.action$.pipe(
    ofType(
      deviceMgtActions.DeviceMgtActionTypes.LOAD_DEVICES
    ),
    switchMap((action: deviceMgtActions.LoadDevices) =>  this.restApiService.getAll('/iot/Devices/AllDevices').pipe(
   
        mergeMap((devices: DeviceModel[]) => [
          new deviceMgtActions.LoadDevicesSuccess(devices),
          new deviceMgtActions.ShowLoader(false),
                 ]),
        catchError((error) =>
          of(
            new deviceMgtActions.LoadDevicesFail(error),
            new deviceMgtActions.ShowLoader(false)
          )
        )
      )
    )
  );

device.reducer

switch (action.type) {
case DeviceMgtActionTypes.LOAD_DEVICES_SUCCESS:
  return {
    ...state,
    devices: action.payload,
    error: '',
  };
case DeviceMgtActionTypes.LOAD_DEVICES_FAIL:
  return {
    ...state,
    devices: [],
    error: action.payload,
  };

devices.ts

getDevices(): void {
     this.store.dispatch(new deviceMgtActions.ShowLoader(true));
     this.store.dispatch(new deviceMgtActions.LoadDevices());
}

constructor

constructor(private store: Store<fromDeviceMgt.State>)
 this.store.pipe(select(fromDeviceMgt.getDevices),
    takeWhile(() => this.componentActive))
    .subscribe((devices: DeviceModel[]) => {
      this.devices = devices;});
}

I have found the answer. in the constructor when you listen to the getdevices you have to use cloneDeep to create a deep copy of the value.

 this.store
  .pipe(
    select(fromDeviceMgt.getDevices),
    takeWhile(() => this.componentActive)
  )
  .subscribe((devicesLoaded: DeviceModel[]) => {
    this.devices = cloneDeep(devicesLoaded);
  });

you have to import cloneDeep from 'lodash/cloneDeep';

Dedicate a copy of the array to it.

this.x = [...this.y]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM