7

I'm using keys pipe in *ngfor loop. Data are fed in JSON.

    @Pipe({
      name: 'keys'
    })
    export class KeysPipe implements PipeTransform {
      transform(value, args: string[]): any {
        if (!value) {
          return value;
        }

        let keys = [];
        for (let key in value) {
          keys.push({key: key, value: value[key]});
        }
        return keys;
      }
   }

--

<div *ngFor="let item of jsonObject | keys">
        <p>{{ item.value.code }}</p>
</div>

The problem is when I delete on of the element in JSON, ngFor is not updated.

I have tried two option already:

  • calling this.applicationRef.tick(); after element delete, no change
  • impure pipe "pure: false". This caused enormous memory usage in chrome in hundreds of MBs and I had to kill the process.

If there any other way?

Thanks!

daemon
  • 372
  • 1
  • 4
  • 24

2 Answers2

6

One way which you can try:

delete(id) {
  this.jsonObject = this.jsonObject.filter(x => x.id !== id);
}

This way you won't mutate the original array. That's crutial thing for pipe

See also

Community
  • 1
  • 1
yurzui
  • 205,937
  • 32
  • 433
  • 399
  • Thanks for pointing me to the right direction. I have filtered the object by key name and used filter & reduce. Actual code is here if anyone is interested: http://codepen.io/anon/pen/MbxOeG – daemon Dec 20 '16 at 22:04
5

Pure pipes dont run unless the reference or value is changed. To fix this add pure: false to your Pipe decorator. See Pipes

ex.

@Pipe({
    name: 'keyVal',
    pure: false
})
export class KeyValPipe implements PipeTransform {
    ...
}

EDIT I didnt see that the OP had already done this. Another option is to set a temp variable and then assign jsonObject to it thus creating a new reference. You could also try a deep copy from temp to jsonObject

ZaksBack
  • 189
  • 3
  • 10