Skip to content

Facing issue in img upload when using uploadthing v4.x.x ++(using 7.3.0) #277

Open

Description

@20200015-anhh

Got Image Tool: uploading failed because of TypeError: Cannot read properties of undefined (reading 'reduce')
when im trying to upload an image.

my img:

image: {
                        class: ImageTool,
                        config: {
                            uploader: {
                                uploadByFile: async (file: File) => {
                                    console.log(file);

                                    // upload to uploadthing
                                    const [res] = await uploadFiles([file], 'imageUploader')
                                    console.log(res);
                                    return {
                                        success: 1,
                                        file: { url: res[0].fileUrl },
                                    };
                                },
                            },
                        }

my uploadFiles:

import type { OurFileRouter } from '~/app/api/uploadthing/core'
import {generateReactHelpers} from "@uploadthing/react";

export const { uploadFiles } = generateReactHelpers<OurFileRouter>();

my router:

import { createUploadthing, type FileRouter } from 'uploadthing/next-legacy'
import {currentUser} from "~/lib/auth";


const f = createUploadthing()

export const ourFileRouter = {
  imageUploader: f({ image: { maxFileSize: '4MB' } })
    .middleware(async (req) => {
        console.log(req)
      const user = await currentUser()
      if (!user) throw new Error('Unauthorized')
      return { userId: user.id }
    })
    .onUploadComplete(async ({ metadata, file }) => {console.log(file)}),
} satisfies FileRouter

export type OurFileRouter = typeof ourFileRouter

Can someone help me

Activity

  1. jsperafico commented on Jan 28, 2025

    @jsperafico

    Hey @20200015-anhh ,

    I'm not extremely knowledgeable on EditorJS nor Typescript itself, but I managed to make it work.

    Sure, my use case is completely different than yours, since I have no reason to save the images on a S3 bucket nor database and that's because I will serve them in my /public folder itself. So in other words, I just need to render what is already being served in the public folder. The use case might not make sense for you, but it does for me.

    Using node version:

    node -v
    v23.6.1

    Here is the relevant content from my package.json file.

    {
      "type": "module",
      "scripts": {
        "dev": "vite",
      },
      "dependencies": {
        "@editorjs/editorjs": "^2.30.7",
        "@editorjs/image": "^2.10.1",
        "react": "^18.3.1",
        "react-dom": "^18.3.1"
      },
      "devDependencies": {
        "@types/node": "^22.9.1",
        "@types/react": "^18.3.12",
        "@vitejs/plugin-react": "^4.3.3",
        "typescript": "~5.6.2",
        "vite": "^5.4.10"
      }
    }

    My component.tsx looks like this:

    import { useState } from "react";
    
    import EditorJS, { ToolConstructable } from '@editorjs/editorjs'
    
    import ImageTool from '@editorjs/image'
    
    export const Component = () => {
      const [content, setContent] = useState("");
    
      const editor = new EditorJS({
        readOnly: false,
        holder: 'editor',
        autofocus: true,
        tools: {
          image: {
            class: ImageTool,
            config: {
              uploader: {
                uploadByFile: async (file: File) => {
                  console.log(file)
                  console.log(`/${encodeURI(file.name)}`)
    
                  return {
                    success: 1,
                    file: {
                      url: `/${encodeURI(file.name)}`,
                    }
                  }
                },
                uploadByUrl: async (url: string) => {
                  console.log(url)
                  console.log(`/${url.split('/')[-1]}`)
    
                  return {
                    success: 1,
                    file: {
                      url: `/${url.split('/')[-1]}`,
                    }
                  }
                }
              }
            }
          },
        },
        data: JSON.parse(localStorage.getItem('content'))
      })
    
      const printMessage = (value: string) => {
        const message = document.getElementById('message')
        if (message)
          message.innerText = value
      }
    
      const saveToLocalStorage = () => {
        editor.save().then((outputData) => {
          localStorage.setItem('content', JSON.stringify(outputData))
          printMessage(`Document content saved at '${new Date().toLocaleString()}'`)
        }).catch((error) => {
          alert('Unable to save the data in Local Storage')
          console.log(error)
        })
      }
    
      const clearLocalStorage = () => {
        editor.clear()
        localStorage.removeItem("content")
        printMessage('')
      }
    
      setInterval(saveToLocalStorage, 60000)
    
      return (
        <div className="pt-20">
          <article id="editor"></article>
          <div className="grid grid-cols-2 gap-4">
            <p id="message" className="bg-cyan-800 text-cyan-100 rounded-sm p-4 col-span-2"></p>
            <Button onClick={saveToLocalStorage} className="text-cyan-800 hover:text-cyan-100 hover:bg-cyan-800">Save</Button>
            <Button onClick={clearLocalStorage} className="text-cyan-800 hover:text-cyan-100 hover:bg-cyan-800">Clear</Button>
          </div>
        </div>
      )
    }

    So, while "updating" the image, it did saved the information correctly:

    {
      "time": 1738082234704,
      "blocks": [
        {
          "id": "q1PHuyT-IM",
          "type": "header",
          "data": {
            "text": "Hey this might work this time!",
            "level": 1
          }
        },
        {
          "id": "5pkBzMiNWw",
          "type": "image",
          "data": {
            "caption": "Dammmmmmmm",
            "withBorder": false,
            "withBackground": false,
            "stretched": false,
            "file": {
              "url": "/hey.svg"
            }
          }
        }
      ],
      "version": "2.30.7"
    }

    I am well aware that this isn't necessarily what you would like to do, but speaking stricktly @editorjs/image component-wise it did worked for me.

    I hope it helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions