Change File Name Automatically

Hi there, Any idea how I can automatically change the name of the file to the origin file name when I upload it? Should I input this somewhere in my database? For instance the excel name is Model.xlsx but it appears like that in the picture (see attached). I basically plan to add a FileName String to my model Attachment in my schema.prisma, but then when I call the uploadthing service I can save the name only if the upload were succeed I can do it sending the string when I call the service or I could save after the uploading service answer succeed but I have to get the name of the file first when I use the uploadform Any idea how to modify the pages to make this happen? Thanks a lot Thanks for the help Yuccie
No description
19 Replies
YUCCIE
YUCCIEOP10mo ago
Any idea how to modify the pages to make this happen? Thanks a lot Hey there, just following up, anyone has any idea?
Alky
Alky10mo ago
Check https://docs.uploadthing.com/api-reference/react#uploadbutton, on the code example, right on this snippet:
onBeforeUploadBegin={(files) => {
// Preprocess files before uploading (e.g. rename them)
return files.map(
(f) => new File([f], "renamed-" + f.name, { type: f.type }),
);
}}
onBeforeUploadBegin={(files) => {
// Preprocess files before uploading (e.g. rename them)
return files.map(
(f) => new File([f], "renamed-" + f.name, { type: f.type }),
);
}}
React – uploadthing
Docs for the best file uploader to date
YUCCIE
YUCCIEOP10mo ago
Thanks @Matheus Lasserre, will check ok Monday 🙏- so no need to store the new name in my db somewhere with this approach?
Alky
Alky10mo ago
i think you would need a reason to save it in your db. Usually people just saves the URL on the DB. Fetch file -> get the metadata
YUCCIE
YUCCIEOP10mo ago
I have done what you mentioned and updated my FileUpload.tsx file (see attached), but the name still is random numbers instead of the name of my file.
No description
YUCCIE
YUCCIEOP10mo ago
My goal is to preserve the file name after Upload here is the name of the file I obtain (3d5eacf2-7cc9-4bbd-b9a7-918c93dd1700-lzt3v2.xlsb) instead of my file name (Financial model.xlsb)
Alky
Alky10mo ago
Aren't you confusing the fileName with the fileKey? See a callback response on my end:
No description
Alky
Alky10mo ago
The file name is kept, the URL uses the fileKey. but if you try do download it, you'll download the file with the proper name
YUCCIE
YUCCIEOP10mo ago
Probably. Let me show you what I meant. 1/ I upload the file on my side so that my user see in their side the following (see attached picture). 2/ Even if the fileKey is random numbers assigned to each different files, I want to display in the user view (the one attached), the FileName and not the FileKey.
No description
YUCCIE
YUCCIEOP10mo ago
and I know that once it downloads the fileName correctly appears but it seems there is no way to actually display to my user the name (fileName) directly (before they download) in the dashboard.
YUCCIE
YUCCIEOP10mo ago
Here is my code for the display (attached). The attachment.name = FileKey, while I want this to be = FileName
No description
Alky
Alky10mo ago
Oh, got it. The attachments array comes from your DB?
YUCCIE
YUCCIEOP10mo ago
Correct, here is how the db looks like :
model Attachment {
id String @id @default(uuid())
name String
url String @db.Text

courseId String
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)

createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

@@index([courseId])
}
model Attachment {
id String @id @default(uuid())
name String
url String @db.Text

courseId String
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)

createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

@@index([courseId])
}
Alky
Alky10mo ago
So you want to save the correct name into your db, or you doesnt want to have to save the name at all? If it's the first one, you can just use the download callback to save it. If it's the second case, you can read the file from the URL provided by your db and then get the name from the metadata
YUCCIE
YUCCIEOP10mo ago
I want the easiest way of doing it. What matters at the end is just to display the correct name of the file (i,e FileName and not FileKey). The file upload component link to the URL field and I use it it my attachment form component. See my code below:
<FileUpload
endpoint="courseAttachment"
onChange={(url) => {
if (url) {
onSubmit({ url: url});
}
}}
/>
<FileUpload
endpoint="courseAttachment"
onChange={(url) => {
if (url) {
onSubmit({ url: url});
}
}}
/>
Alky
Alky10mo ago
The easiest way is to just pass the Name of the file to your db on the same callback you use to save it in your db. I believe that "onSubmit" saves it to your db, right? Instead of receiving just the URL, send the fileName together. At your OnClientUploadComplete, send the URL and also the FileName, since it's available. Then propagate it to your onSubmit and save it to your DB
YUCCIE
YUCCIEOP10mo ago
I am not sure where to reflect this exactly, I literally began coding 3 weeks ago lol. Would you mind writing the additional lines you would incorporate on these files: the file-upload.tsx, the attachment-form (where I call the file-upload component)? That would be much appreciated so that I can see better what your suggestion is. Also, I guess there is no need to modify the route.ts and core.ts of Uploadthing. Thanks for the help thus far. File-upload.tsx:
"use client";

import { UploadDropzone } from "@/lib/uploadthing";
import { ourFileRouter } from "@/app/api/uploadthing/core";
import { toast } from "sonner";

interface FileUploadProps {
onChange: (url?: string) => void;
endpoint: keyof typeof ourFileRouter;
};

export const FileUpload = ({
onChange,
endpoint
}: FileUploadProps) => {
return (
<UploadDropzone
endpoint={endpoint}
onClientUploadComplete={(res) => {
onChange(res?.[0].url);
}}
onUploadError={(error: Error) => {
toast.error(`${error?.message}`);
}}
/>
);
}
"use client";

import { UploadDropzone } from "@/lib/uploadthing";
import { ourFileRouter } from "@/app/api/uploadthing/core";
import { toast } from "sonner";

interface FileUploadProps {
onChange: (url?: string) => void;
endpoint: keyof typeof ourFileRouter;
};

export const FileUpload = ({
onChange,
endpoint
}: FileUploadProps) => {
return (
<UploadDropzone
endpoint={endpoint}
onClientUploadComplete={(res) => {
onChange(res?.[0].url);
}}
onUploadError={(error: Error) => {
toast.error(`${error?.message}`);
}}
/>
);
}
The reference in my attachment-form.tsx of the file-upload:
<FileUpload
endpoint="courseAttachment"
onChange={(url) => {
if (url) {
onSubmit({ url: url});
}
}}
/>
<FileUpload
endpoint="courseAttachment"
onChange={(url) => {
if (url) {
onSubmit({ url: url});
}
}}
/>
Alky
Alky10mo ago
Yeah, of course.
export const FileUpload = ({
onChange,
endpoint
}: FileUploadProps) => {
return (
<UploadDropzone
endpoint={endpoint}
onClientUploadComplete={(res) => {
onChange({url:res?.[0].url, fileName:res?.[0].fileName});
}}
onUploadError={(error: Error) => {
toast.error(`${error?.message}`);
}}
/>
);
}
export const FileUpload = ({
onChange,
endpoint
}: FileUploadProps) => {
return (
<UploadDropzone
endpoint={endpoint}
onClientUploadComplete={(res) => {
onChange({url:res?.[0].url, fileName:res?.[0].fileName});
}}
onUploadError={(error: Error) => {
toast.error(`${error?.message}`);
}}
/>
);
}
<FileUpload
endpoint="courseAttachment"
onChange={(e:{url:string, fileName:string}) => {
if (e.url) {
onSubmit({ url: e.url, fileName:e.fileName});
}
}}
/>
<FileUpload
endpoint="courseAttachment"
onChange={(e:{url:string, fileName:string}) => {
if (e.url) {
onSubmit({ url: e.url, fileName:e.fileName});
}
}}
/>
You would need to change your interfaces accordingly. e.g:
interface FileUploadProps {
onChange: (e: {url?:string, fileName:string}) => void;
endpoint: keyof typeof ourFileRouter;
};
interface FileUploadProps {
onChange: (e: {url?:string, fileName:string}) => void;
endpoint: keyof typeof ourFileRouter;
};
Then, i'm guessing the onSubmit is the function that pass those argumentos to your API, right? Change it to receive not only the URL, but also the fileName, and pass it as the "name" field in your db
YUCCIE
YUCCIEOP10mo ago
Thanks Matheus. I have tried out this code but still not working. Superweird. When I do this on the FileUIpload page (i.e change the export const FileUpload and change the Interface. I get an error only on the fileName saying "Property fileName does not exist on type UploadFileREsponse<null>"
Want results from more Discord servers?
Add your server