0

I want access my method that is in my class after i upload some file but i am getting error that function is not defined.

my html:

<input type="file" id="myFiles">

my javascript:

class fileRead{
constructor(){
  this.myInput = document.getElementById("myFiles");
}

addListener = () =>{
    this.myInput.addEventListener('change', function(){
        this.call(this);
    })
}

call = (fileData) =>{
  console.log(fileData);
   }
}
 const a = new fileRead();
 a.addListener();
Jakub Menšík
  • 174
  • 1
  • 10
  • 2
    Partially the problem is [How to access the correct `this` inside a callback?](https://stackoverflow.com/q/20279484) the biggest problem here is that `function(){ this.call(this); })` expects `this` to have *two different values*. One time it must be a `fileReadt` object, in order to do `.call` on it, another time it has to be the element in which is passed into that call. You are better off binding that directly `this.myInput.addEventListener('change', this.call)` or alternatively using an arrow function and the event parameter `e => this.call(e.target)` – VLAZ Oct 02 '20 at 14:49
  • nice e => this.call(e.target) its working thanks mate. – Jakub Menšík Oct 02 '20 at 14:55

2 Answers2

2

Since you used an arrow function in a class property your function addListener is only defined on the initialization by the constructor and not in the prototype.

You could try to declare your class function as follows:

addListener () {
    this.myInput.addEventListener('change', function(){
        this.call(this);
    })
}

Source: https://medium.com/@charpeni/arrow-functions-in-class-properties-might-not-be-as-great-as-we-think-3b3551c440b1

1

You don't need => arrow notation to define class methods. You do need => notation when defining addEventListeners, this helps all your code remain in the same scope.

In the below example, the keyword this will always refer to the fileRead class instance. If you need to know who exactly triggered the event, you can use the event target.

class fileRead {
    constructor(){
        this.myInput = document.getElementById("myFiles");
    }

    addListener(){
        this.myInput.addEventListener('change', (event) => {
            this.call(event);
        })
    }

   call(event){
        // you can use event.target to know what form field changed
        // or you can just access this.myInput to know the form field content
        console.log(event.target.fileData);
        console.log(this.myInput.fileData);
   }
}

 const a = new fileRead();
 a.addListener();
Kokodoko
  • 26,167
  • 33
  • 120
  • 197