0

A form I use to upload a book cover to Cloudinary has an input type='file' on it. However I'd like to allow no image upload too that is when the form submits there is no file provided to input type='file'. Cloudinary responds with Request failed with status code 400.

This is how I try to mock a file to upload it to Cloudinary inside an action.

export const addBook = (bookData, history) => (dispatch) => {
    const cloudinaryUrl = 'https://api.cloudinary.com/v1_1/*****/upload';
    const cloudinaryUploadPreset = '*****';

    const formData = new FormData();

    bookData.cover[0] && formData.append('file', bookData.cover[0]);

    if (!bookData.cover[0]) {
        const blob = new Blob([''], { type: 'image/png' });
        blob['lastModifiedDate'] = '';
        blob['name'] = 'mockImageFile';
        blob['webkitRelativePath'] = '';
        blob['size'] = 7654;

        formData.append('file', blob);

        /* const f = new File([''], 'filename', { type: 'image/jpeg' });
        formData.append('file', f); */
    }

    formData.append('upload_preset', cloudinaryUploadPreset);

    axios({
        url: cloudinaryUrl,
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        data: formData
    })
... ...

Still Cloudinary responds with Request failed with status code 400. How do I convince it to take a programmatically created 'file'?

The goal is to handle an upload with no file.

El Anonimo
  • 1,759
  • 3
  • 24
  • 38

2 Answers2

1

You need to convert blob data to a data URI which will be accepted by the file parameter to Cloudinary's upload method.

Please try below codebase to convert blob data to data URI. which you can append it to formdata.

const blob = new Blob([""],{ type: "image/png" }); blob["lastModifiedDate"] = ""; blob["name"] = "mockImageFile"; blob["webkitRelativePath"] = "";

blob["size"]=7654;

var reader = new FileReader();

var blob_base64data; reader.readAsDataURL(blob); reader.onloadend = function() { blob_base64data = reader.result; }; formData.append("file", blob_base64data);

  • What could cause an error `TypeError: setting a property that has only a getter` here? It seems setting props on `blob` caused that. – El Anonimo Dec 30 '18 at 18:08
  • Though I could create a blob in the browser console. Perhaps the rror abiove was caused by smth in my code further the chain. – El Anonimo Dec 30 '18 at 18:21
  • Please refer : https://stackoverflow.com/questions/42386027/upload-image-blob-to-cloudinary – Tejas Mulay Dec 30 '18 at 18:25
  • I'll get back to it tomorrow. It's getting late here. Thank you. JIC you're curios the complete repo is on https://github.com/ElAnonimo/booklister The action that utilizes the Cloudinary upload is in client/src/action/bookActions.js -> addBook. – El Anonimo Dec 30 '18 at 18:29
  • The error `TypeError: setting a property that has only a getter` weas caused by `blob['size'] = 7654`. Still getting an error from Cloudinary though. When logging your `blob_base64data` to the console I get `undefined`. – El Anonimo Dec 30 '18 at 20:59
  • I moved the code like this. `let blob_base64data; reader.readAsDataURL(blob); reader.onloadend = function() { blob_base64data = reader.result; console.log('blob_base64data:', blob_base64data); formData.append('file', blob_base64data); }; ` `blob_base64data` puts `"data:image/png;base64,"` to the console. Is it what `blob_base64data` should look like for an empty file? – El Anonimo Dec 30 '18 at 21:16
1

You can either perform a check for an empty file before uploading to Cloudinary and not upload to Cloudinary if there is no file or you can use a default image everytime there is no file uploaded instead of creating a blob.

Aditi Madan
  • 236
  • 1
  • 6