1

I'm trying to do multiple file upload using angular 2.

This is the function I'm using to extract data to variable

fileJSON

, which later I push into array fileArray: Array = [];.

  var that2 = this.fileArray;
     for (var i = 0; i < this.files.length; i++) {
                (function (file) {
                    var reader = new FileReader();
                    let parts = file.name.split(".");
                    reader.onload = function (e) {
                        let view = new Uint8Array(this.result);
                        var data = Array.prototype.map.call(view, function (byte: any) {
                            return ('0' + (byte & 0xFF).toString(16)).slice(-2);
                        }).join('');

                        let fileJSON = { "Filename": parts[0], "Extension": parts[1], "DateCreated": new Date(), "Data": data, "TripId": "", "TypeId": 0 };

                        that2.push(fileJSON);

                    }
                    reader.readAsArrayBuffer(file);
                })(this.files[i]);
            }
        this.editUploadedFiles();

After this I want to show a list of files by using

 <tr ng-repeat="file in fileArray">

 <td>{{file.Filename}}</td>

However this gives me

TypeError: Cannot read property 'Filename' of undefined

My editUploadedFiles() function where I want to get a list of all the files look like this:

   editUploadedFiles() {

        console.log(this.fileArray);
        this.fileArray.forEach(function (element) {
            console.log(element.Filename);
        });

        this.next(); // this just hides and shows some form div's and enables button that calls function "finish()"

    }

However I get the same error while trying to print out element.Filename.

But when I press "Next" button again, I'm calling this function caled "finish()"

finish() {

        this.fileArray.forEach(function (element) {
            console.log(element.Filename);
        });
    }

Basically its almost the same but here it shows filenames without any problems!

I think it has to do something with asynchronous operations, but I have no how to await them.

19
  • try changing this.fileArray.forEach(function (element) { console.log(element.Filename); }); to this.fileArray.forEach(function () { console.log(this.Filename); }); Commented Mar 6, 2018 at 12:58
  • @messerbill hey thanks for quick reaction, I'm getting " 'this' implicitly has type 'any' because it does not have a type annotation" error Commented Mar 6, 2018 at 13:02
  • so try changing this.fileArray.forEach(function (element) { console.log(element.Filename); }); to for (let item of this.fileArray) { console.log(item.Filename) } Commented Mar 6, 2018 at 13:05
  • TypeError: Cannot read property 'Filename' of undefined ... I don't think that function was the problem because it returns good results in the "finish" function if you see my main post Commented Mar 6, 2018 at 13:09
  • 1
    This looks like Angular JS not Angular 2 Commented Mar 12, 2018 at 9:12

1 Answer 1

2
+25

FAIR WARNING: This is some of the hackiest code that I have written in a very long time. It should accomplish what you are trying to do without having to us the IIFE that you have embedded within your for() loop.

// Your code:
/*
var that2 = this.fileArray;
for (var i = 0; i < this.files.length; i++) {
  (function (file) {
    var reader = new FileReader();
    let parts = file.name.split(".");
    reader.onload = function (e) {
      let view = new Uint8Array(this.result);
      var data = Array.prototype.map.call(view, function (byte: any) {
        return ('0' + (byte & 0xFF).toString(16)).slice(-2);
      }).join('');

      let fileJSON = { "Filename": parts[0], "Extension": parts[1], "DateCreated": new Date(), "Data": data, "TripId": "", "TypeId": 0 };

      that2.push(fileJSON);

    }
    reader.readAsArrayBuffer(file);
  })(this.files[i]);
}
this.editUploadedFiles();
*/

// Updated code:
let fileUploadCounter = 0;

this.fileArray.map((file) => {
  const fileParts = file.name.split('.');
  const reader = new FileReader();
  reader.onload = function (e) {
    const view = new Uint8Array(this.result);
    var data = Array.prototype.map
      .call(view, function (byte: any) {
        return ('0' + (byte & 0xFF).toString(16)).slice(-2);
      })
      .join('');

    fileReadFinished({ 
      "Filename": parts[0], 
      "Extension": parts[1], 
      "DateCreated": new Date(), 
      "Data": data, 
      "TripId": "", 
      "TypeId": 0 
    });
  };
  
  reader.readAsArrayBuffer(file);
});

function fileReadFinished(json) {
  if (fileUploadCounter === this.fileArray.length) {
    this.editUploadedFiles();
  }
}.bind(this)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.