AlZ
AlZ

Reputation: 29

Get image buffer from formData

Im making a form with Next 14 using server actions and integrating some WYSIWYG text editor (ReactQuill). Im getting the form values in the server side but I dont know how to get the buffer value of the images to handle them. Here is the code.

Simplified form:

"use client"

export default function NewCompositionForm() {
    const [content, setContent] = useState("");

    const createCompositionAction = actions.createComposition.bind(null, content);

    return (
<form
                className="bg-bgCustom pt-4 h-screen rounded-md px-2"
                action={createCompositionAction}
            >
...

<div className="flex">
                        <label htmlFor="edition" className="w-1/6 text-xl">
                            Imágenes
                        </label>
                        <input
                            type="file"
                            id="images"
                            name="images"
                            className="w-5/6 rounded-md px-2 py-1 text-xl"
                            placeholder="Introduce Editor"
                            multiple
                        />
                    </div>

                    <div className="flex flex-col">
                        <label htmlFor="ext_media" className="text-xl mb-4">
                            Descripción y/o anotaciones
                        </label>
                        <ReactQuill
                            value={content}
                            onChange={setContent}
                            theme="snow"
                            id="description"
                            name="description"
                            className=" bg-slate-50"
                            modules={quillModules}
                            formats={quillFormats}
                            placeholder="Escribe aquí toda la información de la obra."
                        />
                    </div>

<button type="submit">Agregar</button>
</form>

This the server side:

"use server"

export async function createComposition(content, formData) {
    console.log("Content: ", content)
    console.log("FormData: ", formData)

    console.log(formData.getAll('images'))
}

This is the terminal output:

Content:  <p><a href="DUDE" rel="noopener noreferrer" target="_blank"><strong>DUDE</strong></a></p>
FormData:  FormData {
  [Symbol(state)]: [
    { name: 'type', value: 'camara' },
    { name: 'title', value: 'TITULO!!!' },
    { name: 'rev', value: '' },
    { name: 'length', value: '' },
    { name: 'edition', value: '' },
    { name: 'images', value: [File] },
    { name: 'images', value: [File] }
  ]
}
File {
  size: 13397612,
  type: 'image/png',
  name: 'Porsche 911 Blue Render.png',
  lastModified: 1706694592197
}

``

So how do I handle this multiple files from here?

Thanks

Upvotes: 0

Views: 740

Answers (1)

AlZ
AlZ

Reputation: 29

Here is the solution for the server action

"use server";

import fs from "fs";
import path from "path";
import util from 'util'

import { redirect } from "next/navigation";
import { revalidatePath } from "next/cache";
import { db } from "@/lib/db";


//-------- Definitions -------
const writeFileAsync = util.promisify(fs.writeFile)

export async function createComposition(content, formData) {
    console.log("Content: ", content);
    console.log("FormData: ", formData);
    const title = formData.get("title");



    //-------- Image file server handler --------

    const files = formData.getAll("images");

    const filePath = path.join("public", "/compositions", title);

    if (!fs.existsSync(path.resolve(filePath))) {
        fs.mkdirSync(path.resolve(filePath), { recursive: true });
        console.log("Directory created");
    }

    const writePromises = files.map(async (file) => {
        if (file.type === "image/jpeg") {
            const bytes = await file.arrayBuffer();
            const buffer = Buffer.from(bytes);
            await writeFileAsync(`${path.resolve(filePath)}/${file.name}`, buffer);
        }
    });

    await Promise.all(writePromises)

}

Upvotes: 0

Related Questions