Cancel background process when leaving a component to another?

Viewed 968

I am using this libray:

https://github.com/VadimDez/ng2-pdf-viewer

I have created a repository with an example of my problem.

https://github.com/YeisonVelez11/pdf

I am generating a pdf, and this works well. but if the pdf has not finished loading and I navigate to another component, I get an error.

Basically when I go back to a preview, I get a problem because the pdf that is being loaded can not be canceled. I do not know what trick I can do to get out of the document view at any time.

enter image description here

  <pdf-viewer [src]="archivo_adjunto"
              *ngIf="archivo_adjunto"
              [render-text]="false"
              [original-size]="true"
              [page]="1"
              [autoresize]="true"
              [show-all]="true"
              style="display: block;"
              (page-rendered)="pageRendered($event)"
  ></pdf-viewer>

ionViewDidLoad() {
this.archivo_adjunto="./assets/documents/Resumen Ejecutivo Autoevaluacion.pdf"

}

This is done in Ionic, but the functionality is in Angular.

3 Answers

In large-scale apps or in components that deal with bunch of observables or subjects or BehaviorSubjects, it is good practice to unsubscribe the observables when you are leaving the component in order to prevent problems like memory leaks or slowing down system.


 ngOnDestroy(){
   this.ObservableOrSubsject1$.unsubscribe();
   this.ObservableOrSubsject2$.unsubscribe();
   ....
 }

Also do not forget to implement OnDestroy to the class.

export MyComponent implements OnInit, OnDestroy

There is another good way that I actually like and you can use while dealing with subscriptions; in which you can provide a subject Like:

private onDestroy$: Subject = new Subject();

and when using any observable (e.g: mapping or subscribing) pipe with takeUntil:

ngOnInit(){
   this.ObservableOrSubsject1
     .pipe(takeUntil(this.onDestroy$))
     .subscribe((result: IResult) => {
       this.result= Object.assign({}, result);
   });

and in ngOnDestroy just pass "this.onDestroy$.next()":

ngOnDestroy(){
   this.onDestroy$.next();
 }

Again, Do not forget to implement OnDestroy to the class.

At the end, I recommend using Ngrx/Store and Ngrx/Effects to manage your states and unify the events in your application; which will save you from lots of headaches and keeps your application in an standard architecture.

Looking at ng2-pdf-viewer/src/app/pdf-viewer/pdf-viewer.component.ts,

The @Input() src is checked in loadPDF():

private loadPDF() {
    if (!this.src) {
      return;
    }
[. . .]
}

And this method is called on ngOnChanges event.

  ngOnChanges(changes: SimpleChanges) {
    if (isSSR()) {
      return;
    }

    if ('src' in changes) {
      this.loadPDF();
    } else if [. . .]
  }

I believe you just have to change your value for src , which is currently in archivo_adjunto, into undefined or null in one of the lifecycle events of ionic when exiting a page. Perhaps on ionViewWillLeave, ionViewWillUnload or on ngOnDestroy. Changing the src value should trigger the ngOnChanges in the PdfViewerComponent which then calls the loadPDF().

Let me know what worked for you.

Just implement OnDestroy and define a method named ngOnDestroy in your component. Handle the cleanup/cancellation of ongoing work there. This method will be automatically called whenever any component is removed from the DOM.

export class MyComponent implements OnDestroy() {
    //...

    ngOnDestroy() {
       // do the work here
    }

    //...
}
Related