Strange problem encountered when transferring data to and from API using Typescript and Prisma

I'm encountering a strange issue that I can't quite pinpoint. It could be related to mysql, prisma, typescript, or nextjs.

I created the following model to display all product categories and add them to the database.

Prisma Model:

model ProductCategory {
  id          String    @id @default(uuid()) @db.VarChar(128)
  name        String    @db.VarChar(100)
  desc        String    @db.MediumText
  image       Bytes     @db.Blob
  created_at  DateTime  @default(now())
  modified_at DateTime  @updatedAt
  products    Product[]
}

Categories page

import LoadImage from '@/app/components/LoadImage';
import prisma from '@/prisma/client';

const Categories = async () => {
    const categories = await prisma.productCategory.findMany();
    console.log(categories);

    return (
        <>
            {categories && categories.map(({ id, desc, name, image }) => (
                <div key={id} className='border rounded mx-auto max-w-[18rem] min-h-[18rem] grid grid-rows-card items-center content-center p-2'>
                    <LoadImage alt={name} image={image} />
                    <h4 className='text-lg font-medium'>{name}</h4>
                    <p className='text-sm'>{desc.slice(0, 80)}{desc.length > 80 && "..."}</p>
                </div>
            ))}
        </>
    )
}

export default Categories

LoadImage page

"use client"
import Image from 'next/image'

interface Props {
    image: Buffer,
    alt: string
}

const LoadImage = ({ image, alt }: Props) => {
    console.log(image);

    return (!image) ? (
        <div className='relative min-w-full min-h-full'>
            <Image src="/fallback.jpg" layout='fill' objectFit='contain' alt={alt} />
        </div>
    ) : (
        <div className='relative min-w-full min-h-full'>
            <Image src={URL.createObjectURL((new Blob([Uint8Array.from(image)])))} layout='fill' objectFit='contain' alt={alt} />
        </div>
    )
}

export default LoadImage

LoadImage page cannot be run on server that is why i seperated it to run on client. because of blob type. Categories page gets the categories from prisma and runs a map function display them all.

The problem I am facing is that when I console.log categories on Categories page I get following object

{
    id: 'dfed08fe-036a-4256-97ec',
    name: 'Dairy',
    desc: 'This category includes Milk, cheese, yogurt, butter, cream, ice cream, cottage cheese...',
    image: <Buffer 52 49 46 46 fa 99 00 00 57 45 42 50 56 50 38 20 ee 99 00 00 50 66 04 9d 01 2a b0 04 63 03 3e 6d 34 94 48 24 31 2d ab a7 72 fa 72 20 0d 89 67 6e 96 93 ... 39376 more bytes>,
    created_at: 2023-12-29T03:30:11.517Z,
    modified_at: 2023-12-29T03:30:11.517Z
  }

but after I pass it to LoadImage function and console.log it surpringly becomes following object

{type: 'Buffer', data: Array(8981)}

AKA

export interface Image {
  type: string;
  data: Buffer;
}

API to add product category

export async function POST(request: NextRequest) {
  const body = await request.formData();

  const image: Blob = body.get("image") as File;
  const data = {
    name: body.get("name")?.toString()!,
    desc: body.get("desc")?.toString()!,
    image,
  };

  const validation = productCategorySchema.safeParse(data);

  if (!validation.success) {
    return NextResponse.json(validation.error.message, { status: 400 });
  }

  const bufferImage = Buffer.from(await image.arrayBuffer());
  const newCategory = await prisma.productCategory.create({
    data: {
      name: data.name,
      desc: data.desc,
      image: bufferImage,
    },
  });

  return NextResponse.json(newCategory);
}

I don't know what happens in the middle.

Another thing is that when adding product category I don't have to bundle image into another object and send it.

Please let me know if you need any more info. I already spend hours looking for solution but i am confused why it does that.

EDIT:

I was able to solve it using alternate method but question still remains about why there is inconsistency in data type when uploading image vs downloading.

I solved it by just passing id instead of image itself and refetching the product categories.

Answer №1

My interpretation is that prisma serves as an ORM, acting as a connection manager without directly managing the files themselves.

When it comes to images, you need to host them separately and provide prisma with the location for retrieval. View this (GitHub discussion for reference)

Prisma does not support direct image uploads since it's not a traditional database, but it can supply metadata like id, string, name, URL, etc., about the image.

Downloading poses no problem because Prisma simply provides the file location, leaving the actual transaction handling to the client.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Receiving an error while passing properties to a React component: "Property 'firstName' is not found on type 'Readonly<{}>'."

As a beginner in React, I need some patience I'm attempting to create a simple component where users can input their first and last names, update the values, and see them displayed after clicking a button. However, I keep encountering TypeScript comp ...

The triggering of routing in Next.js is not established by useEffect

I'm facing an issue with my Next.js dynamic page that uses routing based on steps in the state. The route is supposed to change whenever a step value changes, like from null to "next" or back. However, the useEffect hook doesn't seem to be reacti ...

Different ways to pass a component function's return value to a service in Angular

On my HTML page, I am presenting job details within Bootstrap panels sourced from a JSON array using an ngFor loop. Each panel showcases specific job information along with a unique job ID. The panel is equipped with a click event which triggers the execut ...

Use the double data type in MySQL to handle null values when blank form fields are submitted

Currently, I am facing an issue with a form that I have created to update a mysql database using PHP and HTML. In my MySQL database, I have set the data type as double (3,1). The problem arises when I submit data to the database and leave some form input f ...

Unusual Behavior of *ngIf and jQuery in Angular 5: A curious case

I'm encountering a strange issue when using the expand-collapse feature of Bootstrap 4 with *ngIf for expansion and collapse. I noticed that the jQuery doesn't work when *ngIf is used, but it works fine when *ngIf is removed. HTML: <div cla ...

Combine two streams under certain conditions using RxJs

When working with streams, I am facing a scenario where I have two server calls to make in order to get the required response. However, if the first call returns data, I do not want to execute the second call. I have been struggling to find the proper comb ...

Laravel Rest API and Github Authentication for Next.js login

I am facing an issue with GitHub authentication login. My setup involves using Laravel API for the backend and Next.js for the frontend. The goal is to allow users to log in with their GitHub accounts. I have already installed the Laravel Socialite package ...

Applying Conditional Rendering in React using API Data Retrieval

I'm facing an issue: I need to display only the "nameProcess" and "id" in the table that have the attribute "error = true" in the json file. I've fetched the data but now I'm struggling to implement the condition inside my function. Can an ...

Guide on creating a 4-point perspective transform with HTML5 canvas and three.js

First off, here's a visual representation of my objective: https://i.stack.imgur.com/5Uo1h.png (Credit for the photo: ) The concise question How can I use HTML5 video & canvas to execute a 4-point perspective transform in order to display only ...

Encountering a Nextjs net::ERR_ABORTED 404 error while accessing the production server configured with

After successfully building and deploying my app locally without any errors, I encountered a frustrating issue when deploying it on the server. Every static file accessed at /_next/static/ resulted in a net::ERR_ABORTED 404 error. While the pages' HTM ...

What is the method for obtaining the union type of interface values (including string enums)?

How can I achieve the following ? Given : enum FooEnum1 { Foo = "foo", }; enum FooEnum2 { Foo = 1, }; interface FooInterface { foo1 : FooEnum1, foo2 : FooEnum2, foo3 : string, foo4 : number, }; I am interested in cre ...

When posting on social platforms, the URL fails to display any metadata

We recently completed a project (Web Application) using React .net core with client-side rendering in React. One challenge we encountered was that when the app loads in the browser, it only displays the static HTML initially without the dynamic meta tags. ...

Angular - Sharing data between components with response value

I am currently in the process of restructuring my project, focusing on establishing communication between unrelated components while also waiting for a return value from a function call. Imagine having component1 with function1() and component2 with funct ...

How come I receive the message 'Error: Invalid hook call' when trying to invoke a hook within a function?

Help needed! I keep encountering the 'Error: Invalid hook call' message while using a hook in my Next.js app. Despite following all guidelines and placing it inside a function component, this issue persists, and I'm at a loss as to why. Serv ...

Modifying Checkbox BorderWidth in Material UI v5

Seeking assistance with adjusting the checkbox border width in Material UI v5. I currently have a custom checkbox and would like to remove the border width. Despite trying numerous solutions, I have been unsuccessful so far. checkbox <Checkbox de ...

Error: The integer provided in the Stripe payment form is invalid in the

I'm encountering an error that I can't seem to figure out. I believe I'm following the documentation correctly, but Stripe is not able to recognize the value. Have I overlooked something important here? https://stripe.com/docs/api/payment_i ...

Is it possible to transform a webpack configuration into a Next.js configuration?

i have come across a webpack configuration setup from https://github.com/shellscape/webpack-plugin-serve/blob/master/recipes/watch-static-content.md: const sane = require('sane'); const { WebpackPluginServe: Serve } = require('webpack-plugin ...

The interface 'Response<ResBody>' has been incorrectly extended by the interface 'Response'

I am currently working with typescript and express in a node.js environment. Whenever I compile my code, I encounter the following bug: node_modules/@types/express-serve-static-core/index.d.ts:505:18 - error TS2430: Interface 'Response<ResBody>& ...

How can I obtain the model values for all cars in the primary object?

const vehicles={ vehicle1:{ brand:"Suzuki", model:565, price:1200 }, vehicle2:{ brand:"Hyundai", model:567, price:1300 }, vehicle3:{ brand:"Toyota", model ...

Angular 8: How to Retrieve Query Parameters from Request URL

Can I retrieve the GET URL Query String Parameters from a specific URL using my Angular Service? For example, let's say I have a URL = "http:localhost/?id=123&name=abc"; or URL = ""; // in my service.ts public myFunction(): Observale<any> ...