0

I'm writing a script that enables me to create an object that uploads files and that should have methods to get properties such as the total size of the files uploaded, let me show you:

function FileUploader = function (to){
    let html = "some html with the form...";
    to.append(html);
    let input = 'someSelector...';
    let allSizes = [];
    let allSrcs = [];
    let totalSize = 0;
    input.on('change', function (){
        //some validation
        let data = new FormData();
        //for loop to append the input files
        let request = createRequest(); //createRequest returns a request...
        request.addEventListener("load", function (evt){
             for( let i = 0; i<input.files.length; i++){
                 totalSize+= input.files[i].size;
                 allSizes.push(input.files[i].size);
             }
             let response = JSON.parse(e.currentTarget.responseText);
             for(let i = 0; i<response.length; i++){
                allSrcs.push(response[i]);
             }
             alert("Ok");
        );
        //other request handlers
        request.open("POST", 'someLocalPath');
        request.send(data);
    });
}

Uploader.prototype.getSrcs= function (){
    //the problem comes here, I can't pass the value of any variable in the object
}

I have tried transforming the let variables into this assignments like this:

 function FileUploader = function (to){
    let html = "some html with the form...";
    to.append(html);
    let input = 'someSelector...';
    this.allSizes = [];
    this.allSrcs = [];
    this.totalSize = 0;
    input.on('change', function (){
        //some validation
        let request = createRequest(); //createRequest returns a request...
        request.addEventListener("load", function (evt){
             for( let i = 0; i<input.files.length; i++){
                 this.totalSize+= input.files[i].size;
                 this.allSizes.push(input.files[i].size);
             }
             let response = JSON.parse(e.currentTarget.responseText);
             for(let i = 0; i<response.length; i++){
                this.allSrcs.push(response[i]);
             }
             alert("Ok");
        );
    });
}

In the last case I get undefined errors such as cannot read property push of undefined.

I really hope you can help me, thank you a lot!

  • Inside of a `function` you get a new `this`, no longer the outer one that you wanted. Read up on fat-arrow-closures. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_binding_of_this https://stackoverflow.com/questions/28371982/what-does-this-refer-to-in-arrow-functions-in-es6 – Thilo Aug 06 '17 at 06:33
  • How do you create an instance? Make sure to use `new` in the version with the `this.` assignments. And how do you call `getSrcs`? That will determine what `this` is... – trincot Aug 06 '17 at 06:35
  • Thank you a lot thilo I'll check it out. –  Aug 06 '17 at 06:43
  • Thanks trincot. I create an instance in onload event of the windowI create a new object: let uplaoder = new FileUploader(); Then when other button is clicked I call getSrcs $("#showResult").click(function (){ uploader.getSrcs(); }); –  Aug 06 '17 at 06:47

1 Answers1

1

For everyone looking for a quick solution easy to understand here's a solution:

function Person() {
  var that = this;
  that.age = 0;

  setInterval(function growUp() {
    // The callback refers to the `that` variable of which
    // the value is the expected object.
    that.age++;
  }, 1000);
}

That's the most basic example I found. I hope it helps you.