question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

React Dashboard crashing after adding files a second time

See original GitHub issue

Hello everyone,

I tried to use the React Dashboard component within my application. When I add files for the first time, there is no problem. However if afterwards I want to add files again, my app crashes and I get the following error.

loggers.js:29 [Uppy] [17:07:15] Using Core v1.8.2
loggers.js:29 [Uppy] [17:07:16] Using react:Dashboard v1.6.2
loggers.js:29 [Uppy] [17:07:16] Installing react:Dashboard to a DOM element '[object HTMLDivElement]'
loggers.js:29 [Uppy] [17:07:16] Using react:Dashboard:StatusBar v1.5.2
loggers.js:29 [Uppy] [17:07:16] Installing react:Dashboard:StatusBar to react:Dashboard
loggers.js:29 [Uppy] [17:07:16] Using react:Dashboard:Informer v1.4.2
loggers.js:29 [Uppy] [17:07:16] Installing react:Dashboard:Informer to react:Dashboard
loggers.js:29 [Uppy] [17:07:16] Using react:Dashboard:ThumbnailGenerator v1.5.5
loggers.js:29 [Uppy] [17:07:16] Using AwsS3 v1.5.2
loggers.js:29 [Uppy] [17:07:16] Using XHRUpload v1.5.2
loggers.js:29 [Uppy] [17:07:16] [Dashboard] resized: 748 / 548
loggers.js:29 [Uppy] [17:08:14] Added file: ck74xz8x900013h617gk99fb6-AWS variant1 (1).png
 id: uppy-ck74xz8x900013h617gk99fb6/aws/variant1//1//png-1d-10-10-18-19-1e-image/png-76743-1579343286944
 type: image/png
loggers.js:29 [Uppy] [17:08:14] [ThumbnailGenerator] Generated thumbnail for uppy-ck74xz8x900013h617gk99fb6/aws/variant1//1//png-1d-10-10-18-19-1e-image/png-76743-1579343286944
loggers.js:29 [Uppy] [17:08:14] [ThumbnailGenerator] Emptied thumbnail queue
component.js:191 Uncaught (in promise) TypeError: Cannot read property 'length' of undefined
    at renderComponent (component.js:191)
    at setComponentProps (component.js:38)
    at buildComponentFromVNode (component.js:224)
    at idiff (diff.js:105)
    at innerDiffNode (diff.js:230)
    at idiff (diff.js:150)
    at diff (diff.js:30)
    at renderComponent (component.js:127)
    at setComponentProps (component.js:38)
    at renderComponent (component.js:124)
    at setComponentProps (component.js:38)
    at buildComponentFromVNode (component.js:224)
    at idiff (diff.js:105)
    at innerDiffNode (diff.js:230)
    at idiff (diff.js:150)
    at diff (diff.js:30)
    at renderComponent (component.js:127)
    at rerender (render-queue.js:9)
renderComponent @ component.js:191
setComponentProps @ component.js:38
buildComponentFromVNode @ component.js:224
idiff @ diff.js:105
innerDiffNode @ diff.js:230
idiff @ diff.js:150
diff @ diff.js:30
renderComponent @ component.js:127
setComponentProps @ component.js:38
renderComponent @ component.js:124
setComponentProps @ component.js:38
buildComponentFromVNode @ component.js:224
idiff @ diff.js:105
innerDiffNode @ diff.js:230
idiff @ diff.js:150
diff @ diff.js:30
renderComponent @ component.js:127
rerender @ render-queue.js:9
Promise.then (async)
enqueueRender @ constants.js:10
setState @ component.js:39
_handleDoneEntering @ preact-css-transition-group.js:475
(anonymous) @ preact-css-transition-group.js:461
endListener @ preact-css-transition-group.js:265
setTimeout (async)
transition @ preact-css-transition-group.js:270
componentWillEnter @ preact-css-transition-group.js:316
performEnter @ preact-css-transition-group.js:460
(anonymous) @ preact-css-transition-group.js:520
componentDidUpdate @ preact-css-transition-group.js:519
renderComponent @ preact.esm.js:810
setComponentProps @ preact.esm.js:676
renderComponent @ preact.esm.js:746
setComponentProps @ preact.esm.js:676
buildComponentFromVNode @ preact.esm.js:842
idiff @ preact.esm.js:397
innerDiffNode @ preact.esm.js:516
idiff @ preact.esm.js:439
innerDiffNode @ preact.esm.js:516
idiff @ preact.esm.js:439
innerDiffNode @ preact.esm.js:516
idiff @ preact.esm.js:439
diff @ preact.esm.js:348
render @ preact.esm.js:991
rerender @ Plugin.js:128
(anonymous) @ Plugin.js:28
Promise.then (async)
(anonymous) @ Plugin.js:22
update @ Plugin.js:89
(anonymous) @ index.js:270
(anonymous) @ index.js:1345
iteratePlugins @ index.js:1344
updateAll @ index.js:269
(anonymous) @ index.js:240
(anonymous) @ index.js:46
_publish @ index.js:45
setState @ index.js:27
setState @ index.js:281
setPluginState @ Plugin.js:73
toggleAddFilesPanel @ index.js:460
onclick @ PickerPanelTopBar.js:111
eventProxy @ preact.esm.js:308

I get the error no matter if I add files then upload them and then add files again or if I add files then try to add more files again.

The stack of my application:

The source code of my component.

import React from 'react';
import cuid from 'cuid';
import Uppy from '@uppy/core';
import { Dashboard } from '@uppy/react';
import AwsS3 from '@uppy/aws-s3';
import Webcam from '@uppy/webcam';
import '@uppy/core/dist/style.css';
import '@uppy/dashboard/dist/style.css';
import '@uppy/webcam/dist/style.css';
import { UpdatePhoto } from '@/api/actions/device';

type UploadState = {
    photos: string[];
};

type UploadProps = {
    photos: UpdatePhoto[];
};

class Upload extends React.Component<UploadProps, UploadState> {
    private uppy: Uppy.Uppy<Uppy.TypeChecking>;

    constructor(props: UploadProps) {
        super(props);
        this.uppy = Uppy({
            autoProceed: false,
            allowMultipleUploads: false,
            debug: true,
            restrictions: {
                allowedFileTypes: ['image/*'],
            },
            onBeforeFileAdded: (currentFile, files) => {
                if (currentFile.source !== 'fromServer') {
                    const modifiedFile = {
                        ...currentFile,
                        name: `${cuid()}-${currentFile.name}`,
                    };
                    return modifiedFile;
                }
            },
        });

        this.state = {
            photos: [],
        };
    }

    async componentDidMount(): Promise<void> {
        this.uppy.use(AwsS3, {
            getUploadParameters(file: { name: any; type: any }) {
                return fetch(`${process.env.HOSTNAME}/v2/files/upload`, {
                    method: 'post',
                    headers: {
                        accept: 'application/json',
                        'content-type': 'application/json',
                        Authorization: 'Basic  XXXXXXXXXXX',
                    },
                    body: JSON.stringify({
                        filename: file.name,
                        contentType: file.type,
                    }),
                })
                    .then(response => {
                        // Parse the JSON response.
                        return response.json();
                    })
                    .then(data => {
                        // Return an object in the correct shape.
                        return {
                            method: data.method,
                            url: data.url,
                            fields: data.fields,
                            // Provide content type header required by S3
                            headers: {
                                'Content-Type': file.type,
                            },
                        };
                    });
            },
        });
        this.uppy.on('complete', result => {
            this.setState(prevState => ({
                photos: [...prevState.photos, ...result.successful.map(element => element.name)],
            }));
            //this.props.setFieldsValue({ photos: this.state.photos });
        });
        if (this.props.photos && this.props.photos.length > 0) {
            for await (const photo of this.props.photos as UpdatePhoto[]) {
                this.setState(prevState => ({
                    photos: [...prevState.photos, photo.name],
                }));
                const response = await fetch(photo.url);
                const blob = await response.blob();
                this.uppy.addFile({
                    name: photo.name, // file name
                    type: blob.type,
                    data: blob,
                    source: 'fromServer',
                    isRemote: true,
                });
            }

            this.uppy.getFiles().forEach(file => {
                if (file.source === 'fromServer') {
                    this.uppy.setFileState(file.id, {
                        progress: { uploadComplete: true, uploadStarted: true },
                    });
                }
            });
        }
    }

    componentWillUnmount(): void {
        this.uppy.close();
    }

    render(): JSX.Element {
        return <Dashboard uppy={this.uppy} />;
    }
}

export default Upload;

The code source of my umi page

import React from 'react';
import Upload from '@/components/Upload';

function UploadPage(): JSX.Element {
    return <Upload photos={[]} />;
}

export default UploadPage;

At this point I really don’t see what I’m doing wrong.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:11 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
Konstantin-Sharohincommented, Jul 29, 2020

Hi! The app does not crash when the error raised, but show it in console (I should mention this in my first comment).

https://codesandbox.io/s/happy-galois-m4lkk?fontsize=14&hidenavigation=1&theme=dark

0reactions
stale[bot]commented, Sep 16, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Closing sidebar crashes react application
I am currently working on a dashboard application in react.js. However, after adding some functionality to a child component involving the ...
Read more >
Troubleshooting build errors and crashes
Go to your build details page (find it on the build dashboard if you don't have it open already) and expand any failed...
Read more >
Fixing the 'cannot GET /URL' error on refresh with React ...
The reason for the dreaded Cannot GET /* error is because, if you're at /dashboard and then hit refresh, the browser will make...
Read more >
React Admin Crash Course - YouTube
In this video we will create an interface using React Admin as well as implement a fake REST API with ...
Read more >
React Crash Course for Beginners 2021 - YouTube
Get Started with React.js and learn how to build amazing websites with ReactJS ! Full Project included, 100% free!
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found