Reputation: 397
I want to show a popup after table is completely loaded. Am using load property but it is not working. Is there any other way to achieve this? Without parent-child concept.
following is my code component.ts
export class FileUploadComponent {
public files: UploadFile[] = [];
data: AOA = [ [1, 2], [3, 4] ];
wopts: XLSX.WritingOptions = { bookType: 'xlsx', type: 'array' };
fileName: string = 'SheetJS.xlsx';
showData: boolean = false;
public dropped(event: UploadEvent) {
this.files = event.files;
for (const droppedFile of event.files) {
if (droppedFile.fileEntry.isFile) {
const reader: FileReader = new FileReader();
const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
fileEntry.file((file: File) => {
var filePath = file;
reader.onload = (e: any) => {
const bstr: string = e.target.result;
const wb: XLSX.WorkBook = XLSX.read(bstr, {type: 'binary'});
const wsname: string = wb.SheetNames[0];
const ws: XLSX.WorkSheet = wb.Sheets[wsname];
this.data = <AOA>(XLSX.utils.sheet_to_json(ws, {header: 1}));
};
reader.readAsBinaryString(file);
this.showData = true;
this.infoModal.hide();
});
} else {
this.showData = false;
const fileEntry = droppedFile.fileEntry as FileSystemDirectoryEntry;
}
}
}
showPopUp(){
console.log('yes');
}
}
Following is my component.htm
<div class="modal-body">
<file-drop id="infoFileModal" headertext="Drop files here" (onFileDrop)="dropped($event)" (onFileOver)="fileOver($event)" (onFileLeave)="fileLeave($event)"></file-drop>
</div>
<div class="card-body">
<div *ngIf="showData" class="upload-table table-responsive">
<table #table class="table-bordered table-striped" id="dest_table" (load)="showPopup()">
<tr *ngFor="let row of data">
<td *ngFor="let val of row">
{{val}}
</td>
</tr>
</table>
</div>
<div *ngIf="!showData" class="div-upload">
No Data Found
</div>
</div>
Upvotes: 1
Views: 15865
Reputation:
Okay, so here is another approach.
As your table takes several minutes for rendering, after the data-array has been filled, your only chance is to listen to the change-event as long as it takes. To prevent the showPopUp()-method from being fired with every finished iteration, you use Observable.debounceTime(), which only calls the method when the time past after the last change-event is greater than the given time in milliseconds.
Component
import { Component, OnInit, OnDestroy, ViewChild, AfterViewInit} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {Subscription} from "rxjs/Subscription";
@ViewChild('table') table: any;
private timer= Observable.timer(1000); // wait one second before calling the method
private subscription: Subscription;
ngOnDestroy(): void {
if(this.subscription){
this.subscription.unsubscribe();
}
}
public dropped(event: UploadEvent) {
// ...
reader.readAsBinaryString(file);
this.showData = true;
this.infoModal.hide();
// call the watcher with a delay of one second
// in order to give angular enough time to build up the table
this.subscription = this.timer.subscribe( () => {
this.triggerTableWatcher();
});
// ...
}
triggerTableWatcher() {
// define the object to listen to
const trigger = this.table.changes();
// define the debounce-time (adjust it, if it doesn't fit your needs)
const debounceAt = trigger.debounceTime(1000);
// subscribe to the trigger and tell which method to call eventually
debounceAt.subscribe(() => this.showPopUp());
}
HTML-Template (only the important part of it)
<div class="card-body">
<div *ngIf="showData" class="upload-table table-responsive">
<table #table class="table-bordered table-striped" id="dest_table">
<tr *ngFor="let row of data">
<td *ngFor="let val of row">
{{val}}
</td>
</tr>
</table>
</div>
Upvotes: 1
Reputation:
You can subscribe to the onloadend()-method of FileReader. Please look at the commented part of the code.
public dropped(event: UploadEvent) {
this.files = event.files;
for (const droppedFile of event.files) {
if (droppedFile.fileEntry.isFile) {
const reader: FileReader = new FileReader();
const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
fileEntry.file((file: File) => {
var filePath = file;
reader.onload = (e: any) => {
const bstr: string = e.target.result;
const wb: XLSX.WorkBook = XLSX.read(bstr, {type: 'binary'});
const wsname: string = wb.SheetNames[0];
const ws: XLSX.WorkSheet = wb.Sheets[wsname];
this.data = <AOA>(XLSX.utils.sheet_to_json(ws, {header: 1}));
};
reader.readAsBinaryString(file);
// subscribe to the onloadend()-method here
reader.onloadend = (e) => {
this.showPopUp();
};
this.showData = true;
this.infoModal.hide();
});
} else {
this.showData = false;
const fileEntry = droppedFile.fileEntry as FileSystemDirectoryEntry;
}
}
}
showPopUp(){
console.log('yes');
}
Upvotes: 0
Reputation: 4166
Native table does not have any load
event. This logic should be delegated to the service which loads the data.
Or, as suggested in the comment, you can use ngAfterViewInit()
.
But: If the table has been first rendered, and the you load data, then it will not work
Upvotes: 1