In our component, we have an upload form, and a confirm message.
file-form.component.html
<div class="tab-pane active" id="upload">
<div id="loader-wrapper" *ngIf="isUploadLoaderVisible">
<div id="loader"></div>
<p class="text-center">Uploading</p>
</div>
<div *ngIf="!isFileSubmitted">
<form class="form-horizontal" [formGroup]="fileUploadForm" (ngSubmit)="onSubmit()">
<input type="file" id="file" formControlName="file" (change)="fileChangeEvent($event)">
</form>
</div>
<div *ngIf="isFileSubmitted">
<p class="alert alert-success">
<i class="fa fa-check"></i>
Thanks for upload.
</p>
<p><a class="btn btn-default" [routerLink]="['..']">Back</a></p>
</div>
</div>
file-form.component.ts
import { Component, OnInit, Inject } from '@angular/core';
import {
FormGroup,
Validators,
FormBuilder,
FormControl
} from '@angular/forms';
import { AngularFire, FirebaseApp } from 'angularfire2';
@Component({
selector: 'app-file-form',
templateUrl: './file-form.component.html',
styleUrls: ['./file-form.component.css']
})
export class SfFileFormComponent implements OnInit {
// States togglers
isFileSubmitted: boolean = false;
isUploadLoaderVisible: boolean = false;
// Declarations
fileUploadForm: FormGroup;
uploadedFile;
isFileValid: boolean = false;
uploadedCorrectedFilename: string;
constructor(private formBuilder: FormBuilder,
public af: AngularFire,
@Inject(FirebaseApp) private firebaseApp: firebase.app.App) { }
ngOnInit() {
this.initForm();
}
private initForm() {
let file = '';
this.fileUploadForm = this.formBuilder.group({
file: file
});
}
fileChangeEvent(fileInput: any) {
this.uploadedFile = fileInput.target.files;
let fileType: string = _.toLower(this.uploadedFile[0].type);
if ( fileType === 'application/pdf' ) {
this.isFileValid = true;
console.log('File is valid. Click to upload file', this.uploadedFile[0]);
} else {
this.isFileValid = false;
this.fileUploadForm.reset();
console.log('File is invalid. Cancel Upload and block form submission', this.uploadedFile[0]);
}
}
onSubmit() {
if (this.uploadedFile.length === 1) {
let file: FileList = this.uploadedFile[0];
console.log('Uploading File', file);
this.isUploadLoaderVisible = true;
// Upload to Firebase
this.firebaseApp
.storage()
.ref()
.child('filesdummy/' + file.name)
.put(file)
.then((snapshot) => {
console.log('Uploaded a blob or file!');
this.isUploadLoaderVisible = false;
this.isFileSubmitted = true;
console.log('isFileSubmitted',this.isFileSubmitted);
console.log('isUploadLoaderVisible', this.isUploadLoaderVisible);
});
}
}
}
At form submit, we set our triggers boolean to display the loader. It works perfectly and instantaneously.
The code then submit the file (to firebase in our case) and when the promise resolves, I change the loader isUploadLoaderVisible
to false
and confirmation message one isFileSubmitted
to true.
The upload works and in console, I can see booleans where changed correctly and immediately:
Uploaded a blob or file!
isFileSubmitted true
isUploadLoaderVisible false
But on browser (I use Chrome), the view is not "switched" and the ngIf seems to actually see the isFileSubmitted is now true only if i change window/tab and come back or after a very big delay (30-34 sec). Such as the new boolean value of my triggers where not "passed" to the component before a long time...
Maybe it's because I change the boolean states directly from the then()
promise result? I don't see how to change the booleans in a different way than I did.
Note: The delay can't be cause by uploading time. Since the promise wouldn't be resolve until upload finish, I wouldn't see the Uploaded
console log. And my test file is currently 50kb.
Do you have any idea?