Non-uploadcare default value for image field

I’m trying to use the uploadcare image for my Flask app. For some reason sometimes the default value for the image is a non-uploadcare URL (ie. facebook profile picture, image from another uploadcare project, legacy database entries). For those the widget shows an error “Incorrect value" because it can’t interpret them from the input’s value attribute.

My attempt to handle this would be to detect when a URL is not valid and then upload it automatically.

This looks something like:

var $input = $(this).children('input')
var url = $input.attr('value')
var file = uploadcare.fileFrom('url', url, {
  check_URL_duplicates: 1,
  save_URL_duplicates: 1,
})
var widget = uploadcare.SingleWidget($input)
widget.value(file)

In principle this seems to work except for two problems:

  1. It also re-uploads files already hosted on uploadcare.
  2. The flag check_URL_duplicates doesn’t have any effect: A duplicate is created for every page-reload.

Any suggestions on how else to achieve this?

I was able to solve the first problem using:

var $input = $(this).children('input')
var url = $input.attr('value')

var widget = uploadcare.SingleWidget($input)
widget.onChange(function (file) {
  file.fail(function() {
    var file = uploadcare.fileFrom('url', url, {
      check_URL_duplicates: 1,
      save_URL_duplicates: 1,
    })
    widget.value(file)
  })
})

Hi @more-onion,

Glad you managed to solve the issue on your own. Alternatively, you can check the value to make sure it matches the Uploadcare file URL schema, and if it doesn’t create a new file instance from URL then set the value.

As for checking for URL duplicates, this is not supported in widget’s API yet. You can use it only when upload files in requests. I’ve added a feature request, and we’ll consider adding those options to widget configuration. This might appear in the next major version of our file uploader we’re working on.

Thanks for the explanation.

As far as I can see the URL-parameters are passed to the service correctly as specified in the upload API reference. Does that mean that the upload API itself does not support these parameters? I don’t see how this is widget-API specific.

@Alex It would be great to get a clarification for this wrt to the upload API as well. (see above comment)

The link to the API-docs changed and it’s now here: Uploading Files From URL It still mentions the check_URL_duplicates parameter.

Hi @more-onion

Sorry that it has taken so long to get back to you on this.

Widget’s API doesn’t allow specifying additional parameters such as save_URL_duplicates and check_URL_duplicates. We added this feature not too far ago, and we haven’t implemented it in the widget yet. We’ll consider adding it to the new major version of our file uploader that comes later this year.

Passing those parameters through the settings object, as you tried to do,

var file = uploadcare.fileFrom('url', url, {
      check_URL_duplicates: 1,
      save_URL_duplicates: 1,
    })

wouldn’t work, as the settings object is supposed to contain widget options, not upload request parameters. Keys that are not widget options are ignored.

To be able to use checking for URL duplicates, you need to implement uploading with requests. Here is a basic example of implementation with Axios

const fileUrl = 'https://about.canva.com/wp-content/community/uploads/sites/3/2016/08/Band-Logo.png'
const apiUrl = 'https://upload.uploadcare.com/from_url/'
const tokenUrl = 'https://upload.uploadcare.com/from_url/status/'
const params = {
  'pub_key': 'demopublickey',
  'source_url': fileUrl,
  'store': 'auto',
  'check_URL_duplicates': '0',
  'save_URL_duplicates': '0'
}

function checkStatus(token) {
  axios.get(tokenUrl, {
    params: { token }
  })
    .then(response => console.log(response.data.uuid))
    .catch(error => console.log(error))
}

axios.get(apiUrl, { params })
  .then(response => {
    if (response.data.type === 'token') {
      checkStatus(response.data.token)
    } else {
      console.log(response.data.uuid)
    }
  })
  .catch(error => {
    console.log(error)
  })

You can check it live here.

Hope that helps!