0

I am having some issues with a upload component in my app. The way it works is that i select a type of file i am uploading and then click on upload which will prompt me to select the file to upload. Once i select it uploads the file and processes it on my back end and all that works fine. Except once i am done with the processing i am not able to select a new type or file. It will not work. I have to reload the page and it will work again just fine. So i am wondering what i am missing so that i can process another upload after i finished one. Just as a side note i am using sockets to provide updates on the progress of processing the file.

Below is my component code

export class UploadComponent implements OnInit {

    // csv = null;
    importTypeId;
    message = null;
    uploadedPercentage = 0;
    importTypeOptions$: Observable<Array<IServerDropdownOption>>;
    processedRecord = 0;
    totalRecord = 0;

    constructor(
        private router: Router,
        private uploadService: UploadService,
        private cbLookupService: CouchbaseLookupService,
        private socketService: SocketService
    ) {
        this.importTypeOptions$ = this.cbLookupService.getOptions(DropdownGuids.IMPORT_TYPE);
    }

    ngOnInit() {
    }

    upload($event) {
        this.uploadedPercentage = 0;
        this.message = null;
        const file = $event.target.files[0];

        this.socketService.ioInject('recCount', (count) => {
            this.message = `Total record count ${count}`;
            this.totalRecord = count;
            console.log(this.totalRecord)
        });

        this.socketService.ioInject('recProcessed', (range) => {
            // this.uploadedPercentage = Number(range.rowcount) / Number(range.recCount) * 100;
            this.message = `${file.name} importing..`;
            this.processedRecord = Number(range.rowcount);
            this.totalRecord = Number(range.recCount);
            console.log(`${file.name} importing..${this.processedRecord}`)
        });

        this.socketService.ioInject('recSaved', (payload) => {
            console.log('res saved event ', payload);
            this.message = `${payload.data} Total: ${payload.recordcount}`;
            this.processedRecord = payload.data;
        });

        this.socketService.ioInject('recError', (err) => {
            this.message = `Something went wrong! Please try again. ${err}`;
            this.uploadedPercentage = 0;
        });

        this.uploadService.uploadCsv(file, this.importTypeId).subscribe((event: HttpEvent<any>) => {
                switch (event.type) {
                    case HttpEventType.Sent:
                        this.message = `${file.name} uploading..`;
                        break;
                    case HttpEventType.Response:
                        this.message = event.body.data;
                        break;
                    case 1: {
                        if (Math.round(this.uploadedPercentage) !== Math.round(event['loaded'] / event['total'] * 100)) {
                            this.uploadedPercentage = event['loaded'] / event['total'] * 100;
                        }
                        break;
                    }
                }
            },
            error => {
                console.log(error);
                this.message = 'Something went wrong! Please try again.';
                this.uploadedPercentage = 0;
            });

    }

}

And here is my template Code

<div class="container">
    <div class="medium-space"></div>
    <div class="medium-space"></div>
    <div class="medium-space"></div>
    <div class="row justify-content-center align-items-center">
        <div class="col-md-6 text-center">

            <igx-select [(ngModel)]="importTypeId">
                <igx-prefix>Import Type</igx-prefix>
                <igx-select-item *ngFor="let option of importTypeOptions$ | async"
                                 [value]="option.value">
                    {{ option.name }}
                </igx-select-item>
            </igx-select>
            <br>

            <input type="file" style="display: none;" name="file" id="file" accept=".csv" (change)="upload($event)"/>
            <label for="file" igxButton="raised" igxRipple="white">Upload CSV File</label>

        </div>
        <div class="col-md-12">
            <div class="row">
                <div class="col-md-6 offset-md-3">
                    <br>
                    <p class="text-center">{{ message }}</p>
                    <div class="text-center" *ngIf="uploadedPercentage">
                        <igx-linear-bar [striped]="false" [max]="100" [value]="uploadedPercentage"></igx-linear-bar>
                      
                    </div>

                </div>
            </div>
        </div>
    </div>
</div>
2
  • I had this problem a while ago and I solved if by clearing the value of the input file. <input type="file" [value]="variable"> and then each time a file gets uploaded you reset that variable to null. Also, why are you asking the user to manually select the type of file which he wants to upload if you have this accept=".csv" which will set the file upload to accept only .csv files? Commented Sep 12, 2021 at 19:12
  • Because in my case there is different files from different vendors which have different mappings so user needs to decide what to do with the uploaded file. Commented Sep 13, 2021 at 17:01

1 Answer 1

2

So you use template driven form. You can bind the form input with a field in your .ts file

Do the following

            <input type="file" style="display: none;" name="file" [(ngModel)]="fileInput" id="file" accept=".csv" (change)="upload($event)"/>
            <label for="file" igxButton="raised" igxRipple="white">Upload CSV File</label>

Then declare fileInput to be a class field in your .ts file.

export class UploadComponent implements OnInit {

  fileInput: any;
   ....

 
   

I see you have a compicated workflow for how the files are uploaded. My proposal would be to put a button and let the user manually erase the file only when the file is 100% uploaded and he has been informed about that.

<div *ngIf="uploadedPercentage == 100">
     <button type="button" (click) = cleanUploadedFile()>Clean Uploaded File</button>
</div>

and then go and declare cleanUploadedFile method in your .ts file like

public cleanUploadedFile() {
   this.fileInput = null;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.