bleenco / ngx-uploader

Angular File Uploader
https://ngx-uploader.jankuri.me
MIT License
756 stars 348 forks source link

Prerendering Failed Error #308

Open FreezingCode opened 7 years ago

FreezingCode commented 7 years ago

I'm getting this error quite often in my app. The work around I've been using is to comment out the markup where ngx-uploader is used and the 2 lines in the component ts file for humanizeBytes, refresh the page, and then uncomment the HTML and humanizeBytes code. It will then work for a while before I have to go through the process again. This is on my dev environment. If I push to our test environment it never works. I've tried disabling HMR on my dev environment, but the issue still persists.

My environment is an Angular 4.1.2 app generated by Microsoft's SPA templates (via CLI command dotnet new angular).

Error message:Exception: Call to Node module failed with error: Prerendering failed because of error: ReferenceError: Event is not defined at Object.<anonymous> (C:\Projects\DEV\uploader\ClientApp\dist\main-server.js:9557:7036) at t (C:\Projects\DEV\uploader\ClientApp\dist\main-server.js:9557:711) at Object.defineProperty.value (C:\Projects\DEV\uploader\ClientApp\dist\main-server.js:9557:8917) at t (C:\Projects\DEV\uploader\ClientApp\dist\main-server.js:9557:711) at Object.e.exports (C:\Projects\DEV\uploader\ClientApp\dist\main-server.js:9557:9472) at t (C:\Projects\DEV\uploader\ClientApp\dist\main-server.js:9557:711) at t.exports (C:\Projects\DEV\uploader\ClientApp\dist\main-server.js:9557:1095) at C:\Projects\DEV\uploader\ClientApp\dist\main-server.js:9557:1104 at n (C:\Projects\DEV\uploader\ClientApp\dist\main-server.js:9557:37) at Object.<anonymous> (C:\Projects\DEV\uploader\ClientApp\dist\main-server.js:9557:581) Current directory is: C:\Projects\DEV\uploader

Line 9557 from main-server.js: https://pastebin.com/6U2nwbQF

Component TS file:

import { Component, Input, ViewEncapsulation, Inject, EventEmitter } from '@angular/core';
import { Router } from '@angular/router';
import { Http, RequestOptions, URLSearchParams } from '@angular/http';
import { UploadOutput, UploadInput, UploadFile, humanizeBytes } from 'ngx-uploader';
import { Observable } from 'rxjs/Rx';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';

@Component({
    selector: 'file-upload',
    templateUrl: '../shared/file-upload.component.html',
    styleUrls: ['../shared/file-upload.component.css' ]
})

export class FileUploadComponent {
    srForm: FormGroup;
    formData: any;
    files: UploadFile[];
    uploadInput: EventEmitter<UploadInput>;
    humanizeBytes: Function;
    dragOver: boolean; 
    submitSuccess: boolean = false;

 constructor(private _http: Http,
        private _router: Router,
        private _fb: FormBuilder) {

        this.files = []; // local uploading files array
        this.uploadInput = new EventEmitter<UploadInput>(); // input events, we use this to emit data to ngx-uploader
        this.humanizeBytes = humanizeBytes;

        //form init code removed     
    }

    onUploadOutput(output: UploadOutput): void {
        //console.log(output);
        if (output.type === 'allAddedToQueue') { // when all files added in queue
        } else if (output.type === 'addedToQueue') {
            this.files.push(output.file); // add file to array when added
        } else if (output.type === 'uploading') {
            // update current data in files array for uploading file
            const index = this.files.findIndex(file => file.id === output.file.id);
            this.files[index] = output.file;
        } else if (output.type === 'removed') {
            // remove file from array when removed
            this.files = this.files.filter((file: UploadFile) => file !== output.file);
        } else if (output.type === 'dragOver') { // drag over event
            this.dragOver = true;
        } else if (output.type === 'dragOut') { // drag out event
            this.dragOver = false;
        } else if (output.type === 'drop') { // on drop event
            this.dragOver = false;
        }
    }

    startUpload(requestGuid): void {  // manually start uploading
        console.log('in startupload');
        const event: UploadInput = {
            type: 'uploadAll',
            url: 'http://localhost:51159/api/FileUpload',
            method: 'POST',
            data: null,
            concurrency: 0, // set sequential uploading of files with concurrency 1
            headers: {
               }
        }
        this.uploadInput.emit(event);
    }

    cancelUpload(id: string): void {
        this.uploadInput.emit({ type: 'cancel', id: id });
    }
}

Markup used in component HTML:

<div class="drop-container" ngFileDrop (uploadOutput)="onUploadOutput($event)" [uploadInput]="uploadInput" [ngClass]="{ 'is-drop-over': dragOver }">
                            <h1>Drag & Drop</h1> 
                        </div>
                        <label class="upload-button">
                            <input type="file" ngFileSelect (uploadOutput)="onUploadOutput($event)" [uploadInput]="uploadInput" multiple>
                            or choose file(s)
                        </label>

Using Angular 4.1.2, and ngx-uploader version 3.2.2 (previously using 3.2.1 and issue was happening there as well). I'm new to Angular2+, so a lot of what is going on is foreign to me. If you need more details I will try and provide.

FreezingCode commented 7 years ago

Just to add some more... In regards to the error I listed above: ReferenceError: Event is not defined at Object.

The "Event" it talks about is [Event] from this line in main-server.js: o([n.i(r.HostListener)("dragover",["$event"]),a("design:type",Function),a("design:paramtypes",[Event]),a("design:returntype",void 0)]

(now using ngx-upload 3.3.1)

butsaty commented 6 years ago

I have the same issue. It is relevant only for server rendering (Angular 4.1.2). In case if I move it to Client rendering module then the issue is gone but the ngx-uploader doesn't work(even onFileOver event).

kabelo2ka commented 6 years ago

I'm getting the same error. Is there a workaround this?

kabelo2ka commented 6 years ago

@FreezingCode did you find a solution?

kevinvella commented 6 years ago

Can this be solved by using *ngIf to not render the uploader on the server like:

<div  *ngIf="isBrowser">
<div  class="drop-container" ngFileDrop (uploadOutput)="onUploadOutput($event)" [uploadInput]="uploadInput" [ngClass]="{ 'is-drop-over': dragOver }">
                            <h1>Drag & Drop</h1> 
                        </div>
                        <label class="upload-button">
                            <input type="file" ngFileSelect (uploadOutput)="onUploadOutput($event)" [uploadInput]="uploadInput" multiple>
                            or choose file(s)
                        </label>
</div>
Tomdrouv1 commented 6 years ago

Hi, Is this issue fixed or there is any solution ? Thanks.

retailify commented 6 years ago

@Tomdrouv1 could you check the solution of @kevinvella?

Tomdrouv1 commented 6 years ago

@retailify I already tried this. Using isPlatformBrowser function to check if app is runnig in the browser or not and put it in a variable to use in *ngIf, but still got the issue..

retailify commented 6 years ago

Could you open a git repository with your setup, so I can check this out?

Tomdrouv1 commented 6 years ago

Are you talking about the prerendering setup ? I'm working on a professional project so I can't share all the git repository but if you're only talking about the setup, I can make a repo with the setup.

I followed all steps on https://angular.io/guide/universal

retailify commented 6 years ago

Yes only the setup you are using including the things like package.json and so on, so I have the same setup & releases you are using.

Tomdrouv1 commented 6 years ago

Okay, there it is https://github.com/Tomdrouv1/server-side-rendering-angular-5. Tell me if you need other files

retailify commented 6 years ago

Thx! I've forked the repo.

retailify commented 6 years ago

could you add the UniversalInterceptor to your repo? import {UniversalInterceptor} from "./_services/universal.interceptor"; I need also your src/index.html + polyfills.ts files.

Which node version do you use?

Tomdrouv1 commented 6 years ago

@retailify It's done 😃 .

I use Node 8.9.2

chrisvfabio commented 6 years ago

I'm getting the same issue. I think it's related to this: https://github.com/bleenco/ngx-uploader/blob/ecb99591de36721018d08f1a8478296d654cb34a/src/ngx-uploader/directives/ng-file-drop.directive.ts#L65

Changing Event to DragEvent fixed the issue in my tests

I'm using Angular 5.0.1 and Node 8.9.1

Tomdrouv1 commented 6 years ago

@chrisvfabio I'll try this and hope it will fix the issue for me too! Thanks

chrisvfabio commented 6 years ago

This PR should fix the issue: https://github.com/angular/angular/pull/22905 🎉