Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
20200015-anhh opened this issue Nov 28, 2024 · 1 comment

Comments

@20200015-anhh
Copy link

20200015-anhh commented Nov 28, 2024

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

@jsperafico
Copy link

jsperafico commented Jan 28, 2025

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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants