reactjsreact-reduxreact-dropzone

Trying to get file preview thumbnail to render


Just trying to get a preview thumbnail image to render with onDrop(). Something I have seen on several websites where you drop a document and it shows a thumbnail of the first page. I am either getting a broken link image, or no image at all.

This is what I am using as a reference, although not finding the official documentation too helpful:

https://react-dropzone.js.org/

React-Dropzone image preview not showing

https://medium.com/technoetics/handling-file-upload-in-reactjs-b9b95068f6b

And here is the code I am currently using. This doesn't render a thumbnail, but the Submit and Cancel buttons shift down like something is there, but I don't see anything.

import _ from 'lodash';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { submitDocument } from '../../actions/documents';
import Dropzone from 'react-dropzone';

class SubmitDocuments extends Component {

    constructor() {
        super();
        this.state = {
            filesToBeSent: [],
            filesPreview: [],
        }

        this.handleClick = this.handleClick.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.onDrop = this.onDrop.bind(this);
    }

    handleClick(event) {
        this.setState({
            filesToBeSent: [],
            filesPreview: [],
        });
    }

    handleSubmit(event) {
        event.preventDefault();
        this.props.submitDocument(this.state.filesToBeSent);
    }

    onDrop(acceptedFiles) {
        console.log(acceptedFiles);
        var filesToBeSent = this.state.filesToBeSent;       
        _.map(acceptedFiles, f => {
            filesToBeSent.unshift(f);
        });

        filesToBeSent = _.uniqBy(filesToBeSent, 'name');

        var filesPreview = [];

        _.map(filesToBeSent, i => {
            filesPreview.unshift(
                <div key={i.name}>
                    {/*<h5>{i.name} - {i.size} bytes</h5>*/}
                    <img src={window.URL.revokeObjectURL(i.preview)} />
                </div>
            )            
        });

        this.setState({
            filesToBeSent,
            filesPreview
        });
    }

    render() {
        return (
            <form onSubmit={this.handleSubmit}>
                <div className='panel panel-default'>
                    <div className='panel-heading'>
                        <h4><strong>Submit Documents</strong></h4>
                    </div>

                    <div className='panel-body'>
                        <Dropzone className='dropzone' onDrop={this.onDrop}> 
                            <h3>Click to add files or drag files here to upload</h3>
                        </Dropzone>
                        {this.state.filesPreview}
                        <button type='submit' disabled={this.state.filesPreview.length < 1} className='btn btn-primary'>Submit</button>
                        <button type='button' className='btn btn-danger' onClick={this.handleClick}>Cancel</button>
                    </div>
                </div>
            </form>
        ); 
    }
}

function mapStateToProps(state) {
    return {
        survey_id: state.documents.survey_id
    }
}

export default connect(mapStateToProps, { submitDocument })(SubmitDocuments);

Now changing to the following results in the broken image icon:

<img src={i.preview} />

Things are uploading fine though.

What am I doing wrong here? I feel like my interpretation of preview might be different from what the documentation means, or that it only applies to image files, whereas mine should apply to .pdf, .xlsx., .txt.

EDIT

This is what the console.log(filesToBeSent) looks like.

filesToBeSent

This is what i looks like after lodash _.map(filesToBeSent, i => {}.

i after map


Solution

  • Turns out I would need something like this service to do what I am trying to accomplish:

    FilePreviews.io