Sampath
Sampath

Reputation: 65870

Pipe doesn't update the template when remove a item from array

I was not able to refresh the template after I have removed the item from pages array due to normalizeUri pipe. Same code is working fine without normalizeUri pipe. Can you tell me what was the issue of pipe implementation? i.e. Why template doesn't update if there is pipe.

.html

  <ion-slides pager (ionSlideDidChange)="slideChanged()">
    <ion-slide *ngFor='let page of pages | normalizeUri'>
      <img [src]='page' />
    </ion-slide>
  </ion-slides>

.ts

  async removePage() {
    try {

      await SbSdk.removePage({ page: this.selectedPage });
      let pageIndexToRemove = null;
      this.pages.forEach((p, index) => {
        if (this.selectedPage.pageId === p.pageId) {
          pageIndexToRemove = index;
        }
      });

      this.pages.splice(pageIndexToRemove, 1);
      this.selectedPage = null;

      if (this.pages.length == 0) {//no pages
        this.goToScan();
        return;
      } else {
        setTimeout(() => {
          this.goToSlide(this.pages.length - 1);
        }, 500);
      }
      this.changeDetector.detectChanges();
    }
    catch (err) {
      console.log(err);
    }
  }

pipe.ts

import { Pipe, PipeTransform } from '@angular/core';
import { ImageHandlingProvider } from '../../providers/image-handling/image-handling';
import { Page } from 'cordova-plugin-scanbot-sdk';

@Pipe({
  name: 'normalizeUri',
})
export class NormalizeUriPipe implements PipeTransform {

  constructor(private imageHandlingProvider: ImageHandlingProvider) { }
  transform(pages: Page[]): string[] {
    return pages.map((p) => {
      return this.imageHandlingProvider.normalizeImageFileUri(p.documentPreviewImageFileUri || p.originalPreviewImageFileUri);
    });
  }

}

Upvotes: 1

Views: 743

Answers (2)

Bytech
Bytech

Reputation: 1215

You've created what is considered a Pure pipe. When the type is not specified, that is the default. Pure pipes are only executed "when it detects a pure change to the input value. A pure change is either a change to a primitive input value (String, Number, Boolean, Symbol) or a changed object reference (Date, Array, Function, Object)." (Angular Manual)

To turn your pipe impure, add the false flag to the pipe decorator:

@Pipe({
  name: 'normalizeUri',
  pure: false
})

Because Pure pipes get executed a lot, they are in general discouraged. An impure pipe is called often, as often as every keystroke or mouse-move. (Angular Manual)

Instead, consider normalising your URIs before assigning them to an object that will be rendered in a template.

Upvotes: 0

Paresh Gami
Paresh Gami

Reputation: 4782

You have to use impure pipe for that

@Pipe({
  name: 'normalizeUri',
  pure: false
})

https://blog.angularindepth.com/the-essential-difference-between-pure-and-impure-pipes-and-why-that-matters-999818aa068

But the impure pipe is not reliable to use.

Upvotes: 1

Related Questions