简体   繁体   中英

How do I call a JS callback when a file upload completes?

I'm creating frontend upload for an app with appengine backend.

What I want to make is a file upload solution, and I dont want to be using plupload or those kinds of ready-made solutions.

I basically submitted the images to an iframe and then put a cover while it is uploading. Then after it finishes I performed an ajax call to get the image ids for the next view to be rendered. However, the render is always called before the upload is completed, thus I'm not getting any image ids from the backend. can anyonehelp?

here's my code for the upload

perform_input3:(event)=>
    event.preventDefault()
    $('#product-input-3').hide()
    $('#product-input-3').submit()
    $('#upload-cover').show()
    item_id = $('#item3_id').val()
    app.views.imageselect.render(item_id)

the app.views.imageselect.render(item_id) is below:

render:(data)=>
    @item_id = data
    item_id = @item_id
    $.ajax(
        url: '/get_image_list/'
        type: 'GET'
        dataType: 'json'
        data: {item_id: item_id}
        success:(data) =>
          @payload = data
          $(@el).append imageSelectTemplate(@payload)
          return @
    )

I dont want to be using setTimeout function since it will not be flexible depending on the connection speed. Any help will be appreciated :)

Essentially, your question boils down to this: You want to wait to make your Ajax call to the server until the data you're requesting is available. Getting notifications from the server is tricky (depending on how your backend is implemented), so the best solution to your problem is probably to just make the Ajax call periodically (say, once per second) until you get a successful response from the server.

Here's some code that should do that:

do ajaxCall = =>
  $.ajax
    url: '/get_image_list/'
    type: 'GET'
    dataType: 'json'
    data: {item_id: item_id}
    success: (data) =>
      @payload = data
      $(@el).append imageSelectTemplate(@payload)
    error: ->
      setTimeout ajaxCall, 1000

If you are only targeting modern browsers, then XHR2's FormData can enable a very simple and elegant approach.

The concept is:

  • add file(s) binary data to a FormData object
  • make a $.ajax() call with the FormData object as the AJAX call's "data" parameter
  • when upload is done, the $.ajax()'s success() or complete() callbacks will be triggered

This approach works with the latest Firefox, Chrome, Safari - http://caniuse.com/xhr2 .

See this post for details: Sending multipart/formdata with jQuery.ajax

What you're missing is some sort of callback from the $('#product-input-3').submit() call. I think the following would work (pardon my bad CoffeeScript):

perform_input3:(event)=>
    event.preventDefault()
    item_id = $('#item3_id').val()
    $('#product-input-3').hide()
    $('#upload-cover').show()
    $('#product-input-3').submit()
    $('#target-iframe').ready ->
        app.views.imageselect.render(item_id)

This is predicated on the idea that calling 'submit' immediately puts the target iframe into non-ready state, which seems reasonable, but I'd test it. Once it finishes loading The other option I've seen around is to have the page the iframe loads call back into its parent (top-level) window. In JS, something like:

parent.imageUploaded()

Or, if you want to use bound events:

parent.$(parent.document).trigger('upload-complete')

Where, of course, you've set up an upload-complete event on the top-level document object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM