0

I have the below code (simplified from what I am actually doing). Essentially, I have a class instance with some state and a method that is called by an event listener, which gets a file from the user and uploads it. I have have out how to bind this from within the method to the upload callback, but I can't work out how I would bind the state to the method for when it is called by the event listener. I would like to do this without using ES6 class syntax, because I want to learn prototypes properly before moving on to class syntax.

export default function State() {
  this.message = "hello";
}
State.prototype.uploadMethod = function (e) {
  var reader = new FileReader();
  reader.onload = upload.bind(this);
  function upload() {
    var base64image = reader.result;
    fetch("/api", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ message: this.message, image: base64image }),
    });
  }
  reader.readAsDataURL(e.target.files[0]);
};
const state = new State();
const button = document.querySelector("button");
button.addEventListener("click", uploadMethod);
Max888
  • 3,089
  • 24
  • 55
  • See the linked question's answers, basically: `button.addEventListener("click", state.uploadMethod.bind(state));`. (It would be the same if you were using `class` syntax as well.) – T.J. Crowder May 26 '20 at 10:51
  • Do you mean State.uploadMethod.bind(state)? (notice State is the contructor function, state is the instance). I need a way to do it without using the instance, since I will be constructing the instance elsewhere, also it won't necessarily be called state and I don't want to rely on it being called state. Thanks – Max888 May 26 '20 at 15:26
  • No, I mean `button.addEventListener("click", state.uploadMethod.bind(state));` -- bind the instance (`state`) that you got from `const state = new State();` to the function. – T.J. Crowder May 26 '20 at 15:29
  • Thanks, but I would like to be able to set up uploadMethod on the constructor prior to creating the instance, so it can be used in different contexts – Max888 May 26 '20 at 15:46
  • I don't understand. It *can* be used in different contexts....? – T.J. Crowder May 26 '20 at 15:53
  • I mean for example if somewhere else in my code I run `const differentState = new State()`, I want the method to already be attached and working, rather than then having to also do differentState.uploadMethod.bind(differentState)) – Max888 May 26 '20 at 16:12
  • In that case, bind it in the constructor: In `State`, use `this.uploadMethod = this.uploadMethod.bind(this);` That gets the method from the prototype, binds `this` to it, and then assigns it as an "own" property on the object. In your original example, you'd use it like this: `button.addEventListener("click", state.uploadMethod);` (because it would already be bound). – T.J. Crowder May 26 '20 at 16:14

0 Answers0