1

I'm trying to create a drag and drop area for uploading a single picture and I want to pass it to the application state in the base64 encoded URL using a function onDrop.

import React from "react";
import {useDrop} from 'react-dnd'


export default function MyDropTarget(props) {
    const [drop] = useDrop({
        accept: "box",
        collect: (monitor) => {
                const res = monitor.getItem();
                if (res && res.files) {
                    const reader = new FileReader();
                    reader.onloadend = () => props.onDrop(reader.result);
                    reader.readAsDataURL(res.files[0]);
                }
        },

    });
    return (
        <div ref={drop}>
            Drag item here
        </div>);
};

That's how I use this component:

<DndProvider backend={HTML5Backend}>
  <MyDropTarget style={{height: "100px", width: "100px"}} onDrop={updateImage}/>
</DndProvider>

Since I am new to react-dnd I am having some problems. I got such an error TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'.
I think I do not understand the structure of monitor.getItem() correctly and will be grateful for any hint how to fix it.

Helen
  • 463
  • 2
  • 9
  • 23

1 Answers1

2

My guess is that you need to make sure res.files[0] has a value (not undefined or null).

 if(res.files[0]){
  reader.readAsDataURL(res.files[0]);
 }

You may also try to check the type of res.files[0] is if that doesn't help.

lacrit
  • 115
  • 5
  • strange if I add `if (res && res.files[0])`it doesn't go into the if block at all – Helen Nov 02 '20 at 16:08
  • It kinda suggests that `res.files[0]` is `undefined` or `null` (assuming that previously, with `res && res.files` condition it did enter the if block). Could you maybe provide an example on sandbox, so that we can test it? – lacrit Nov 02 '20 at 18:55
  • You can as well try to output `res.files[0]` before an if statement and verify whether it actually has any value. – lacrit Nov 02 '20 at 18:57
  • res.files[0] is undefined. I don't even know what to do in this case and where the uploaded file is stored. – Helen Nov 03 '20 at 09:25
  • 1
    According to the documentation, `monitor.getItem()` gets the item passed on `endDrag` in a drag component. Since it's a little bit different case I'd rather suggest using `Dropzone.js` (https://github.com/react-dropzone/react-dropzone). It seems to be doing exactly what you're looking for, and in usage example, you'll find file uploading. Hope that this will help :) – lacrit Nov 03 '20 at 09:57
  • Thank you very much, I will try – Helen Nov 03 '20 at 10:01