I have an existing form-upload component which uploads files to the backend this works fine but the problem is that I do not have any visual indicator of how much file i.e. % of file have been uploaded to the server. I believe that it's much needed functionality which is missing in my this component. at this current moment Please wait
stems from app-loader.service.ts (screenshot),
Is it possible for that I am able to modify Please wait
with % of file uploaded
uploaded. I have seen quite a few answers online using progressbar, but I would rather have a solution which makes sense to me and tailored to my specifics.
form-upload.component.ts
import { Component, ViewChild, } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { Subscription } from 'rxjs/Subscription';
import { Observer } from 'rxjs/Observer';
import { HttpClient} from '@angular/common/http';
import { TranslateService } from '@ngx-translate/core';
import { FieldConfig } from '../../models/field-config.interface';
import { WebSocketService, DialogService } from '../../../../../../services/';
import { AppLoaderService } from '../../../../../../services/app-loader/app-loader.service';
import { Http } from '@angular/http';
import { MatSnackBar } from '@angular/material';
@Component({
selector: 'app-form-upload',
templateUrl: './form-upload.component.html',
styleUrls: ['../dynamic-field/dynamic-field.css', 'form-upload.component.css'],
})
export class FormUploadComponent {
@ViewChild('fileInput') fileInput;
config: FieldConfig;
group: FormGroup;
fieldShow: string;
public busy: Subscription[] = [];
public sub: Subscription;
public observer: Observer < any > ;
public jobId: Number;
public fileBrowser = true;
public apiEndPoint = '/_upload?auth_token=' + this.ws.token;
constructor(
protected ws: WebSocketService, protected http: Http, private loader: AppLoaderService,
private dialog:DialogService, public snackBar: MatSnackBar, public translate: TranslateService) {}
upload(location = "/tmp/") {
if(this.config.updater && this.config.parent ){
this.config.updater(this, this.config.parent);
return;
}
this.loader.open();
const fileBrowser = this.fileInput.nativeElement;
if (fileBrowser.files && fileBrowser.files[0]) {
const formData: FormData = new FormData();
formData.append('data', JSON.stringify({
"method": "filesystem.put",
"params": [location + '/' + fileBrowser.files[0].name, { "mode": "493" }]
}));
formData.append('file', fileBrowser.files[0]);
this.http.post(this.apiEndPoint, formData).subscribe(
(data) => {
this.newMessage(location + '/' + fileBrowser.files[0].name);
this.loader.close();
this.snackBar.open("File upload complete.", 'close', { duration: 5000 });
},
(error) => {
this.loader.close();
this.dialog.errorReport(error.status, error.statusText, error._body);
}
);
} else{
this.loader.close();
};
}
newMessage(message){
if(this.config.message){
this.config.message.newMessage(message);
}
}
}
form-upload.component.html
<div id="{{config.name}}" class="dynamic-field form-input" [formGroup]="group" [ngClass]="fieldShow" [class.has-tooltip]="config.tooltip" *ngIf="!config.isHidden">
<div class="top">
<label>{{ config.placeholder | translate }}</label>
<tooltip *ngIf="config.tooltip" [message]="config.tooltip"></tooltip>
</div>
<div *ngIf="config.hideButton;else showButton">
<mat-card-content>
<input type="file" #fileInput accept="{{config.acceptedFiles}}" (change)="upload(config.fileLocation)" [formControlName]="config.name">
</mat-card-content>
</div>
<ng-template #showButton>
<mat-card-content>
<input type="file" #fileInput accept="{{config.acceptedFiles}}" [formControlName]="config.name">
</mat-card-content>
<mat-card-actions class="buttons">
<button mat-button type="button" (click)="upload(config.fileLocation)">Upload</button>
</mat-card-actions>
<mat-error *ngIf="config.hasErrors">{{config.errors}}</mat-error>
</ng-template>
</div>
app-loader.service.ts
import { Injectable } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material';
import { Observable } from 'rxjs/Rx';
import { AppLoaderComponent } from './app-loader.component';
import { TranslateService } from '@ngx-translate/core';
import { T } from '../../translate-marker';
@Injectable()
export class AppLoaderService {
dialogRef: MatDialogRef<AppLoaderComponent>;
constructor(private dialog: MatDialog, private translate: TranslateService) { }
public open(title: string = T('Please wait')): Observable<boolean> {
this.translate.get(title).subscribe(t => {
this.dialogRef = this.dialog.open(AppLoaderComponent, {disableClose: true});
this.dialogRef.updateSize('200px', '200px');
this.dialogRef.componentInstance.title = t;
});
return this.dialogRef.afterClosed();
}
public close() {
this.dialogRef.close();
}
}