Base solution for your next web application
Open Closed

Angular ng2-file-uploader exception on this.uploader.clearQueue() #6303


User avatar
0
cyklussoftware created

I am using version ASP.NET Core + Angular v6.5.0.

I basically copied the image uploading logic from the Profile Picture file upload component and I am having an issue when my custom modal is closing. My code is attached below.

When my close() function runs the uploader.clearQueue(); line, an exception that says TypeError: Cannot read property 'isUploading' of undefined gets thrown. This is part of the file-uploader.class.js file. I think the function that is throwing the exception looks like this:

FileUploader.prototype.removeFromQueue = function (value) {
        var index = this.getIndexOfItem(value);
        var item = this.queue[index];
        if (item.isUploading) {
            item.cancel();
        }
        this.queue.splice(index, 1);
        this.progress = this._getTotalProgress();
};

What's odd is that when I debug this in VS Code, the item variable is defined and isUploading is also defined.

My image upload works and I can see the images reflected on my server, but after running the this.uploader.uploadAll(); function, the queue is not empty. If I check the queue after uploading in the Profile Picture section, the queue is empty. I'm not sure what could be going wrong given that my code is practically a copy. Maybe I'm missing an import somewhere that doesn't throw an error when it's missing?

My component code is below.

import { IAjaxResponse } from '@abp/abpHttpInterceptor';
import { TokenService } from '@abp/auth/token.service';
import { Component, Injector, ViewChild } from '@angular/core';
import { AppConsts } from '@shared/AppConsts';
import { AppComponentBase } from '@shared/common/app-component-base';
import { FileUploader, FileUploaderOptions, FileItem } from 'ng2-file-upload';
import { ModalDirective } from 'ngx-bootstrap';
import { finalize } from 'rxjs/operators';

@Component({
    selector: 'changeRewardImageModal',
    templateUrl: './change-reward-image-modal.component.html'
})
export class ChangeRewardImageModalComponent extends AppComponentBase {

    @ViewChild('changeRewardImageModal') modal: ModalDirective;

    public active = false;
    public uploader: FileUploader;
    public temporaryPictureUrl: string;
    public saving = false;

    private maxProfilPictureBytesUserFriendlyValue = 5;
    private temporaryPictureFileName: string;
    private _uploaderOptions: FileUploaderOptions = {};

    imageChangedEvent: any = '';

    constructor(
        injector: Injector,
        private _tokenService: TokenService
    ) {
        super(injector);
    }

    initializeModal(): void {
        this.active = true;
        this.temporaryPictureUrl = '';
        this.temporaryPictureFileName = '';
        this.initFileUploader();
    }

    show(): void {
        this.initializeModal();
        this.modal.show();
    }

    close(): void {
        console.log("close");
        this.active = false;
        this.imageChangedEvent = '';

        // Clearing the queue gets rid of the files that need to be uploaded.
        // Idk if we actually need to do this if the modal is closing.
        //console.log(this.uploader.queue.length);
        //if(this.uploader.queue.length > 0){
        try {
            this.uploader.clearQueue(); // todo this was causing an exception to be thrown
        } catch (exception){
            console.log(exception);
        }
        //}

        this.modal.hide();
    }

    fileChangeEvent(event: any): void {
        this.imageChangedEvent = event;
    }

    imageCroppedFile(file: File) {
        console.log("cropped file");
        let files: File[] = [file];
        this.uploader.clearQueue();
        this.uploader.addToQueue(files);
    }

    initFileUploader(): void {
        this.uploader = new FileUploader({ url: AppConsts.remoteServiceBaseUrl + '/Reward/UploadRewardImage' });
        this._uploaderOptions.autoUpload = false;
        this._uploaderOptions.authToken = 'Bearer ' + this._tokenService.getToken();
        this._uploaderOptions.removeAfterUpload = true;
        this.uploader.onAfterAddingFile = (file) => {
            file.withCredentials = false;
        };

        this.uploader.onBuildItemForm = (fileItem: FileItem, form: any) => {
            form.append('FileType', fileItem.file.type);
            form.append('FileName', 'RewardImage');
            form.append('FileToken', this.guid());
        };

        this.uploader.onSuccessItem = (item, response, status) => {
            const resp = <IAjaxResponse>JSON.parse(response);
            if (resp.success) {
                this.saving = false;
                abp.event.trigger('rewardImageUploaded', {
                    fileToken: resp.result.fileToken,
                    x: 0,
                    y: 0,
                    width: 0,
                    height: 0
                });
                this.close();
            } else {
                this.message.error(resp.error.message);
            }
        };

        this.uploader.setOptions(this._uploaderOptions);
    }

    guid(): string {
        function s4() {
            return Math.floor((1 + Math.random()) * 0x10000)
                .toString(16)
                .substring(1);
        }
        return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
    }

    save(): void {
        if(this.uploader.queue.length > 0){
            this.saving = true;
            this.uploader.uploadAll();
        }
    }
}

1 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @cyklussoftware

    Have you solved this problem ? If not, could you share your modal's html content as well ?

    Thanks,