skip to Main Content

I have an input file with multiple images upload. I am adding them to Supabase storage as you can see in the server actions, it works fine. When I try adding the images URL’s to the Prisma database it does not work. The "create" is giving an error : Types of property ‘imageUrl’ are incompatible. Here is my code. I omitted the extra fields just to keep it simple. Anyone can help to sport the problem in my code?

The Image Input File

<Input name="image" type="file" multiple={true} required />

The Server Action

export async function createDescription(formData: FormData) {

  const homeId = formData.get("homeId") as string;
  const photos = formData.getAll("image") as string[];

  const photoNames = photos.map((_, index) => `blog-${Date.now()}-${index}`);

  
  const uploadPromises = photos.map((photo, index) => {
    return supabase.storage.from("images").upload(photoNames[index], photo, {
      contentType: "image/png",
      cacheControl: "2592000",
    });
  });

  const uploadResults = await Promise.all(uploadPromises);
  const errors = uploadResults.map((result) => result.error).filter(Boolean);

  if (errors.length > 0) {
    return { error: "Unable to upload one or more blog images to Storage." };
  }

  const paths = uploadResults.map((result) => result.data?.path);
  const photoUrls = paths.map(
    (path) =>
      `${process.env.SUPABASE_URL}/storage/v1/object/public/images/${path}`,
  );

  const { data: imageData } = await supabase.from("blogs").update([
    {
      homeId,
      photoUrls,
    },
  ]);

  if (imageData === null) {
    return { error: "Unable to upload one or more blog images to Storage." };
  }

  const imageFilesUrl = photoUrls.map((url) => ({ url }));

  const data = await prisma.home.update({
    where: {
      id: homeId,
    },
    data: {
      title,
      addedDescription: true,

      HomePhoto: {
        create: {
          imageUrl: imageFiles,
        },
      },
    },
  });

  return redirect(`/create/${homeId}/address`);
}

The Prisma Model

model User {
  id           String  @id @unique
  authId       String  @unique
  email        String  @unique
  firstName    String
  lastName     String
  profileImage String?
  Home         Home[]
}

model Home {
  id           String  @id @default(uuid())
  title        String?
  description  String?
  guests       String?
  bedrooms     String?
  bathrooms    String?
  country      String?
  price        Int?
  categoryName String?

  addedCategory    Boolean @default(false)
  addedDescription Boolean @default(false)
  addedLocation    Boolean @default(false)

  createdAT DateTime @default(now())
  User      User?    @relation(fields: [userId], references: [id])
  userId    String?
  HomePhoto Photo[]
}

model Photo {
  id       String @id @default(uuid())
  imageUrl String

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

  Home   Home   @relation(fields: [homeId], references: [id])
  homeId String
}

2

Answers


  1. Chosen as BEST ANSWER

    I should have used the "photoUrls" array and not the "imageFilesUrl" which can be deleted. Then the call to store each image URL is as below:

    HomePhoto: {
            create: {
              photoUrls.map((url) => ({ imageUrl: url })),
            },
          },
    

  2. what if we change it to, for example, the following?
    supabase will overwrite or conflict if the same image is used many times.

    (after)

    const photoNames = photos.map((_, index) => `blog-${Date.now().toISOString()}-${index}`);
    
    const uploadPromises = photos.map((photo, index) => {
        return supabase.storage.from("images").upload(photoNames[index], photo, {
        contentType: photo.type,
        cacheControl: "2592000",
        });
      });
    

    (before)

    const photoNames = photos.map((_, index) => `blog-${Date.now()}-${index}`);
    const uploadPromises = photos.map((photo, index) => {
      return supabase.storage.from("images").upload(photoNames[index], photo, {
        contentType: "image/png",
        cacheControl: "2592000",
        });
      });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search