-1

I am new to Javascript and I am pulling my hair to understand the following problem. I am writing a fairly complex file reader class. So I am following usual OO practices that I employ in other languages and I created my class which uses a FileReader object. The code is something like this:

class CustomReader{
    constructor(){
        this.reader = new FileReader()
        this.customFunc = {}
    }

    read(file, customFunc){
        this.customFunc = customFunc;
        this.reader.onloadend = this.complexProcess;
        this.reader.readAsText(file);
    }

    complexProcess( ) {
        console.log(this.reader) // ==> At this point, this.reader is UNDEFINED
        this.customFunc()
    }
}

So the problem is that the file is read correctly by means of the read() function. However, when complexProcess() is called at the end of readAsText, the object this.reader is undefined which does not allow me to access the this.reader.result field that I need to continue with my complex processing of the data read from the file.

Does anyone have an explanation on why is that happening? In other languages this would be ok, but I guess that the way JS works is just different from what I am used to (C++, Java, Python, etc.).

I tried searching on Google for similar problems, and tried different ways of implementing this class. None worked and google results were not exactly what I needed.

Counlin
  • 1
  • 1

1 Answers1

0

It's quite simple, it's a problem of context!

In fact, when you write the following code :

        this.reader.onloadend = this.complexProcess;

When the onloadend event is fired, your complexProcess callback will be called.

However, it will be called with the context of the FileReader class, so the this keyword will no longer refer to your CustomReader class, and the reader attribute will no longer exist there.

How can you solve the problem?

You have a bind function in JavaScript that allows you to assign a new context.

class CustomReader{
    constructor(){
        this.reader = new FileReader()
        this.customFunc = {}
        this.complexProcess = this.complexProcess.bind(this); // We apply the current context to the complexProcess function
    }

    read(file, customFunc){
        this.customFunc = customFunc;
        this.reader.onloadend = this.complexProcess;
        this.reader.readAsText(file);
    }

    complexProcess( ) {
        console.log(this.reader) // ==> At this point, this.reader should no longer be UNDEFINED
        this.customFunc()
    }
}

This is a recurring problem in JavaScript that often takes hours to solve. At least you shouldn't run into it again in the future!

Pioupia
  • 339
  • 2
  • 15