skip to Main Content

I’m trying to dispatch a custom event when an XMLHTTPRequest completes, and have a listener capture it and initiate the next action. However, the event listener is not being triggered as expected. I tested the same event listener by adding it to window and it works, but not when the event listener is added in a hook as shown below. What am I doing wrong?

Uploaders.Cloudinary_Direct = function(entries, onViewError) {
  entries.forEach(entry => {
    let formData = new FormData()
    let {
      url,
      fields
    } = entry.meta

    Object.entries(fields).forEach(([key, val]) => formData.append(key, val))
    formData.append("file", entry.file)
    formData.append("upload_preset", "avatar_upload");
    let xhr = new XMLHttpRequest()
    onViewError(() => xhr.abort())
    xhr.onload = () => {
      if (xhr.status === 204) {
        entry.progress(100)
      } else {
        entry.error()
      }
    }
    xhr.onerror = () => entry.error()
    xhr.onreadystatechange = function() {
      if (xhr.readyState == XMLHttpRequest.DONE) {

        console.log("public_id")
        let event = new CustomEvent("cloudinary_external_upload", {
          bubbles: true,
          cancelable: true,
          detail: {
            public_id: get_public_id(xhr)
          }
        });
        this.dispatchEvent(event); // also tried window.dispatchEvent.. in vain
      }
    }
    xhr.upload.addEventListener("progress", (event) => {
      if (event.lengthComputable) {
        let percent = Math.round((event.loaded / event.total) * 100)
        if (percent < 100) {
          entry.progress(percent)
        } else {
          entry.progress(100)
        }
      }
    })

    xhr.open("POST", url, true)
    xhr.send(formData)
  })
}

Hooks.ExternalUpload = {
  mounted() { // <-- This ensures the listener is add only after the component is mounted.
    this.el.addEventListener('cloudinary_external_upload', e => {
      console.log("cloudinary_upload") // <-- This is never printed.

      this.pushEvent("external_upload", {
        id: this.el.id,
        public_id: e.originalEvent.detail.public_id
      });
    });
  }
}

let liveSocket = new LiveSocket("/live", Socket, {
  hooks: Hooks,
  uploaders: Uploaders
})

EDIT: The debug inspector shows the event listener is properly added to the HTML element.
event listener added to element

2

Answers


  1. There might be a couple of issues causing your event listener not to trigger as expected:
    Here’s how you can refactor your code to address these issues:

        Hooks.ExternalUpload = {
      mounted() {
        const el = this.el; // Capture the correct scope
        
        const cloudinaryUploadHandler = function(e) {
          console.log("cloudinary_upload");
          this.pushEvent("external_upload", { id: el.id, public_id: e.detail.public_id });
        };
    
        this.el.addEventListener('cloudinary_external_upload', cloudinaryUploadHandler.bind(this)); // Bind the correct scope
    
        // Clean up event listener when the hook is destroyed
        this.handleEvent("disconnect", () => {
          this.el.removeEventListener('cloudinary_external_upload', cloudinaryUploadHandler);
        });
      }
    }
    
    Login or Signup to reply.
  2. For starters, looking at your custom event…

    xhr.onreadystatechange = function() {
    
      if (xhr.readyState == XMLHttpRequest.DONE) {
          
          console.log("public_id")
    
          let event = new CustomEvent("cloudinary_external_upload", {bubbles: true,  cancelable: true, 
    
            detail: {
    
                public_id: get_public_id(xhr)
            } 
      });
    
        this.dispatchEvent(event);
    

    Why are you dispatching outside of the readystate condition? I would place it inside like so…

    xhr.onreadystatechange = function() {
    
      if (xhr.readyState == XMLHttpRequest.DONE) {
          
      console.log("public_id")
    
      let event = new CustomEvent("cloudinary_external_upload", {bubbles: true,  cancelable: true, 
    
        detail: {
    
            public_id: get_public_id(xhr)
        } 
    
    this.dispatchEvent(event);
    
      });
    

    If left outside you’re dispatching when the custom event doesn’t even exist yet.

    Excuse the mess… FF is really playing up tonight… or maybe SO has a bug.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search