FileReader is not defined with Angular Server Side Rendering

I'm setting Server Side Rendering in a large webapp. It works well for page without FileReader instance. Do you know how can I make FileReader to work with SSR enable?

I found an NPM package for filereader. I installed and import it in server.ts import * as FileReader from 'filereader'; but I got no result from that.

I also added the filereader package in the whitelist of webpack.server.config.ts with no luck again.

I tried to replace FileReader with new Response(blob).text(); but in that case it is the Response which is undefined too.

I also tried window.FileReader() and global.FileReader() and no luck again.

This is the method with FileReader:

function blobToText(blob: any): Observable<string> {
  return new Observable<string>((observer: any) => {
        if (!blob) {
            observer.next("");
            observer.complete();
        } else {
          let reader = new FileReader(); // FileReader is not defined
            reader.onload = event => { 
                observer.next((<any>event.target).result);
                observer.complete();
            };
            reader.readAsText(blob); 
        }
    });
}

Here is the error message

I got: ERROR { Error: Uncaught (in promise): ReferenceError: FileReader is not defined ReferenceError: FileReader is not defined at Observable._subscribe....

Upvotes: 4

Views: 7420

Answers (4)

Cầm Nguyễn
Cầm Nguyễn

Reputation: 21

function blobToText(blob: any): Observable<string> {
    return new Observable<string>((observer: any) => {
        if (!blob) {
            observer.next("");
            observer.complete();
        } else {
            if (typeof window === 'undefined') {
                observer.next(blob);
                observer.complete();
            } else {
                let reader = new FileReader();
                reader.onload = event => {
                    observer.next((<any>event.target).result);
                    observer.complete();
                };
                reader.readAsText(blob);
            }
        }
    });
}

Upvotes: 2

vhbazan
vhbazan

Reputation: 1417

Maybe this answer comes too late but in case anybody else could run into this issue, this solution worked for me, when using Angular 9. So basically you need to create a block of code that only gets executed when your application is on the browser not in the server side:

//Import PLATFORM_ID and Inject from @angular/core
import { Component, OnInit, PLATFORM_ID, Inject } from '@angular/core';

@Component({
  selector: 'app-new-post',
  templateUrl: './new-post.component.html',
  styleUrls: ['./new-post.component.scss']
})
export class NewPostComponent implements OnInit {

//Change the FileReader variable
reader; //before it was: reader: FileReader = new FileReader(); 

//Inject PLATFORM_ID as follow: 
    constructor(  @Inject(PLATFORM_ID) private platformId: any,
                  private readonly activatedRoute: ActivatedRoute,
                  private readonly fileUploadService: FileUploadService) {
    }

     ngOnInit() {
     //Create a code block that only gets executed when it's loaded in the browser: 
        if (isPlatformBrowser(this.platformId)) {
          this.reader = new FileReader();
     }

}

Upvotes: 0

Tony
Tony

Reputation: 20082

You need to install "@types/node"

By this command

npm install --save @types/node

Then in your tsconfig.json add

"typeRoots": [
  "node_modules/@types"
]

If not work open your tsconfig.app.json file add to types section

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "module": "esNext",
    "types": ["node"] // add node here
  },
  "exclude": [
    "src/test.ts",
    "**/*.spec.ts"
  ]
}

Upvotes: 0

guest
guest

Reputation: 31

FileReader is a Web API; use fs object of Node instead, see docs.

Upvotes: 3

Related Questions