1

I know that this question has been asked many times here but I have looked at these answers and couldn't make my code work. I'm using Angular 2. I have input tags for file insertion. File gets to component but when I convert it to array buffer and try to set it to variable my variable remains undefined. I tried to implement callbacks but I think I have done it wrong.

Here is my code:

addPlayer() {
    var nationality = document.getElementById("nationality") as HTMLSelectElement;
    var position = document.getElementById("position") as HTMLSelectElement;
    var shirtnmbr = document.getElementById("shirtnmbr") as HTMLSelectElement;
    var profilePicture = document.getElementById("profilepic") as HTMLSelectElement;
    var inGamePicture = document.getElementById("detailspic") as HTMLSelectElement;
    var player = {
        Club_ID: this.clubId,
        Name: this.capitalization(this.addForm.get("name").value),
        Surname: this.capitalization(this.addForm.get("surname").value),
        Height: this.addForm.get("height").value,
        Weight: this.addForm.get("weight").value,
        BirthDate: this.addForm.get("birthdate").value.formatted,
        Nationality: this.nationalities[nationality.selectedIndex],
        Position: this.order[position.selectedIndex],
        Shirtnmbr: this.shirtNumbers[shirtnmbr.selectedIndex],
        ProfilePicture: this.conversion(profilePicture, function (res) {
            return res;
        }),
        InGamePicture: this.conversion(inGamePicture, function (res) {
            return res;
        })
    };
    console.log(player);  
}

capitalization(str) {
    return str.replace(/\w\S*/g, function (txt) { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); });
}

conversion(element, callback) {
    var file = element.files;
    var result;
    var fileReader = new FileReader();
    fileReader.onload = function () {
        result = fileReader.result;
        callback(result);
    };
    fileReader.readAsArrayBuffer(file[0]);
}

When I log player every property has value except ProfilePicture and InGamePicture(they are undefined). After that I'm planning to send that player to database but currently I can't do that because http.post would run before ProfilePicture and InGamePicture properties get values.

user7479651
  • 689
  • 1
  • 5
  • 14
  • You need to ensure both call backs have completed before you send your data to HTTP i assume? Also just a suggestion, you should use promises or because using Angular 2 then you should use RXJS instead of callbacks. – LiverpoolOwen Sep 06 '17 at 12:27
  • @LiverpoolOwen can you provide an example how can I do that? – user7479651 Sep 06 '17 at 12:31

1 Answers1

0

You are setting ProfilePicture and InGamePicture to values equal to the return value of conversion(), which never returns anything so they will always be undefined. You give a callback which you call, but it does actual nothing (returns the parameter which is never handled).

You need to synchronously complete both FileReader operations before proceeding. If you can only get the results asynchronously then this sounds like a job for Promises, the preferred way these days to handle control flow with multiple asynchronous operations.

jlaitio
  • 1,878
  • 12
  • 13
  • 2
    No, it does not? It sets an onload that *calls* the callback, which only returns the parameter it is given, then immediately discards the result (the `callback(result)` expression is just ran and not stored, hence its return value will be discarded). All this is asynchronous. The `onload` setting does not block program flow and the function will return immediately (with an `undefined` return value). – jlaitio Sep 06 '17 at 12:33
  • that is exactly the problem that I'm facing with. I don't know how to solve it. – user7479651 Sep 06 '17 at 12:35
  • Without delving too deep, as I said, refactoring the control flow as promises would probably accomplish what you want. See https://stackoverflow.com/questions/34495796/javascript-promises-with-filereader for a similar problem. – jlaitio Sep 06 '17 at 12:42
  • I am looking at that example but I don't get how it works. To be precise, I don't know how to implement promises in my code. – user7479651 Sep 06 '17 at 12:50
  • @jlaitio can you tell me how can I store callback(result) to get return value from that function? I'm not familiar with promises. – user7479651 Sep 06 '17 at 13:38