Open joriksp opened 3 weeks ago
I have the same issue. Also, I cannot see any logs in the upload
fn.
Next-admin library version: 6.1.6. Nextjs version: 14.2.16. Operating system: MacOS Sonoma 14.0 Browser: Chrome 130.0.6723.70
Hi,
The upload
function runs on the server side. You need to use it to process the uploading file and return a string (URL) that will be stored in your database and used to find the file when you display the form of the object.
When a form containing a file object is submitted, the client sends file data and information to the server, it catches this information and passes it to the upload
function.
I don't quite understand your request, can you please give more details about your request to see if I'm missing something ?
This is a sample NextAdminOptions code from my project:
const options: NextAdminOptions = {
model: {
User: {
edit: {
fields: {
avatar: {
format: "file",
required: true,
handler: {
upload: async (buffer, { name, type }) => {
const uploadedFile = await upload(
new File([buffer], name)
);
return uploadedFile.url || "";
},
},
},
},
},
},
};
Here, a function inside handler.upload with the same name takes in a File and returns an object with a download reference. Here is its code:
export const upload = async (file: File) => {
const formData = new FormData();
formData.append("file", file);
try {
const response = await fetch(`${fsHost}/upload`, {
method: "POST",
body: formData,
});
if (!response.ok) {
return {
success: false,
message: `Request failed, ${response.status}`,
};
}
const data: UploadedFile = await response.json();
return data;
} catch (error) {
return {
success: false,
message: `Request failed, ${error}`,
};
}
};
if you add any debugging (console.log('example')) to handler.upload, it will not be displayed in the console
Hi @joriksp,
To optimize performance and reduce computation, the form submits only dirty fields, if you don't modify or add a file, the function handler.upload
won't run due to unmodified data. Perhaps this behavior explains why you don't see the log. It's not actually an issue but a default behavior
I hope this explains your issue, if not, please let us know
Hello, the problem is a bit of a misnomer. After selecting an image when I want to save new data the following error appears:
What's the return type of your handler.upload
function? This return type is passed to Prisma in your field, which appears to be named image
.
This error means that you are trying to submit the output of your upload
function without passing through handler.upload
.
@joriksp I had the same problem in my case was that I didn`t add the options on app/api/admin/[[...nextadmin]]/route.ts by default come commented
import { prisma } from "@/prisma";
import schema from "@/prisma/json-schema/json-schema.json";
import { createHandler } from "@premieroctet/next-admin/appHandler";
const { run } = createHandler({
apiBasePath: "/api/admin",
prisma,
schema,
/*options*/
});
export { run as DELETE, run as GET, run as POST };
What's the return type of your
handler.upload
function? This return type is passed to Prisma in your field, which appears to be namedimage
.This error means that you are trying to submit the output of your
upload
function without passing throughhandler.upload
.
handler: {
upload: async (buffer, { name, type }) => {
const uploadedFile = await upload(
new File([buffer], name)
);
return uploadedFile.url || "";
},
},
It returns string (url)
@joriksp I had the same problem in my case was that I didn`t add the options on app/api/admin/[[...nextadmin]]/route.ts by default come commented
import { prisma } from "@/prisma"; import schema from "@/prisma/json-schema/json-schema.json"; import { createHandler } from "@premieroctet/next-admin/appHandler"; const { run } = createHandler({ apiBasePath: "/api/admin", prisma, schema, /*options*/ }); export { run as DELETE, run as GET, run as POST };
Indeed, thanks for the precision
If you are using options, which it seems you are, you need to pass the options
to the createHandler function param. If you don't, any server-side function you add to the options
file (such as handler.upload
) will not be executed. In the example this part is commented because the options
are optional, in your case you need to put options in there.
@joriksp please let me know if you have in the same case
Also, to avoid other problems, we recommend putting options
in the createHandler
function params from the moment you use any options, even if it does not appear to be server-side execution.
Problem description
When using the upload property in the avatar field configuration in the User model, a problem occurs: instead of the expected string returned from the upload handler, the actual file itself is sent in the user change form. This leads to incorrect data processing on the server and can cause errors when saving data.
Steps for playback
const options: NextAdminOptions = { model: { User: { edit: { fields: { avatar: { format: "file", required: true, handler: { upload: async (buffer, { name, type }) => { const uploadedFile = await upload( new File([buffer], name) ); return uploadedFile.url || ""; }, }, }, }, }, }, } }
export default options;