i have that error: image : ['The image must be an image.'], when i send my data to api. how can i fix it?

When I send data to the API, I get an error image : [‘The image must be an image.’]. How can I send it?

function saveFile() {
  while (imagePreview.firstChild) {
    imagePreview.removeChild(imagePreview.firstChild);
  }
  const files = fileInput.files;
  for (let i = 0; i < files.length; i++) {
    const file = files[i];
    let data = JSON.parse(localStorage.getItem("data")) || {};
    data.image = [];
    if (file.type.startsWith("image/")) {
      const img = document.createElement("img");
      img.classList.add("resume--photo");
      const reader = new FileReader();
      reader.onload = () => {
        img.src = reader.result;
        const fileInfo = {
          name: file.name,
          type: file.type,
          dataURL: reader.result,
        };
        data.image.push(fileInfo);

        localStorage.setItem("data", JSON.stringify(data));
      };
      reader.readAsDataURL(file);
      imagePreview.appendChild(img);
    }
  }
}

The rest of the data information is sent, only the image is not sent

const formEl = document.querySelector(".form");
formEl.addEventListener("submit", function (e) {
  e.preventDefault();
  const data = generateFormData();
  fetch("https://resume.redberryinternship.ge/api/cvs", {
    method: "POST",
    headers: {
      Accept: "application/json",
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "POST,PATCH,OPTIONS",
    },
    body: JSON.stringify(data),
  })
    .then((res) => res.json())
    .then((data) => console.log(data))
    .catch((error) => console.log(error));
  console.log(data);
});

This generates data which I then send

function generateFormData() {
  const form = document.getElementById("form");
  const formData = new FormData(form);
  const data = {
    experiences: [],
    educations: [],
  };
  for (let [key, value] of formData.entries()) {
    data[key] = value;
  }
  const storedData = JSON.parse(localStorage.getItem("data"));
  if (storedData) {
    Object.assign(data, storedData);
  }

  return data;
}

I have tried different ways but still can’t solve the problem

The issue with sending the image in your code lies in how you’re trying to include it in the request body. Here’s the breakdown and how to fix it:

Problem:

  • You’re storing the image data as a dataURL within the data object. However, APIs usually expect images to be sent as binary data (e.g., JPEG, PNG).

Solution 1: Sending as FormData:

  1. Modify saveFile to append the image as a Blob instead of a dataURL:

JavaScript

function saveFile() {
  // ... (existing code)

  if (file.type.startsWith("image/")) {
    const reader = new FileReader();
    reader.onload = () => {
      const fileInfo = {
        name: file.name,
        type: file.type,
        data: reader.result, // Use reader.result directly (it's a Blob)
      };
      data.image.push(fileInfo);
      // ... (rest of your code)
    };
    reader.readAsArrayBuffer(file); // Read as ArrayBuffer for binary data
  }
}

In generateFormData , append the image data to the FormData object:
JavaScript

function generateFormData() {
  // ... (existing code)

  for (const imageInfo of data.image) {
    formData.append("image", imageInfo.data, imageInfo.name);  // Append image data as Blob
  }

  // ... (rest of your code)
  return formData;
}

Update the fetch request to send FormData:

JavaScript

fetch("https://resume.redberryinternship.ge/api/cvs", {
  method: "POST",
  // ... (existing headers)
  body: formData, // Send FormData object directly
})
    .then((res) => res.json())
    .then((data) => console.log(data))
    .catch((error) => console.log(error));

Solution 2: Sending as Base64 (Less Preferred):

Modify saveFile to encode the image to base64

JavaScript

function saveFile() {
  // ... (existing code)

  if (file.type.startsWith("image/")) {
    const reader = new FileReader();
    reader.onload = () => {
      const base64Data = reader.result.replace(/^data:,/, ''); // Remove data: URI prefix
      const fileInfo = {
        name: file.name,
        type: file.type,
        data: base64Data, // Base64 encoded image data
      };
      data.image.push(fileInfo);
      // ... (rest of your code)
    };
    reader.readAsDataURL(file); // Read as dataURL for base64 encoding
  }
}

In generateFormData , include the base64 data in the data object:

JavaScript

function generateFormData() {
  // ... (existing code)

  for (const imageInfo of data.image) {
    data.image.push({
      name: imageInfo.name,
      type: imageInfo.type,
      base64: imageInfo.data, // Base64 encoded image data
    });
  }

  // ... (rest of your code)
  return data;
}

Update the fetch request to send JSON with the base64 data:

JavaScript

fetch("https://resume.redberryinternship.ge/api/cvs", {
  method: "POST",
  // ... (existing headers)
  body: JSON.stringify(data), // Send data object with base64 image data
})
    .then((res) => res.json())
    .then((data) => console.log(data))
    .catch((error) => console.log(error));

Choosing the Right Approach:

  • Sending as FormData is generally preferred by APIs as it handles different file types efficiently.
  • Base64 encoding can be an alternative, but it might increase data size and some APIs might not support it.

Additional Tips:

  • Consider error handling in saveFile if file reading fails or the file type is not an image.
  • Check the API documentation for specific requirements or limitations regarding image uploads.