Cause: Trying to serialize an `object` that is not JSON serializable (such as a "[object Date]"). Ensure that only JSON serializable data types are returned

Currently, I am utilizing Prisma along with Next.js. My issue arises when attempting to retrieve content from Prisma within the getStaticProps function; while it successfully fetches the data, I encounter difficulties passing it on to the main component.

export const getStaticProps = async () => {
  const prisma = new PrismaClient();
  const newsLetters = await prisma.newsLetters.findMany();
  console.log(newsLetters);

  return {
    props: {
      newsLetters: newsLetters,
    },
  };
};

Despite displaying the fetched content in this image, an error is generated when trying to pass it as props:

https://i.stack.imgur.com/d34op.png

The error message received states: "Reason: `object` ("[object Date]") cannot be serialized as JSON. Please only return JSON serializable data types."

Answer №1

If you're working with typescript, it's important to note that you cannot directly change the type of createdAt to a string or number, as shown here:

newsletter.createdAt = newsletter.createdAt.toString();
// Error: Type 'string' is not assignable to type 'Date'.

Instead, a workaround is to utilize JSON.stringify within JSON.parse in order to create a serializable object:

export const getStaticProps = async () => {
  const prisma = new PrismaClient();
  const newsletters = await prisma.newsletters.findMany();

  return {
     props: {
        newsletters: JSON.parse(JSON.stringify(newsletters)) // <===
     }
  }
}

Answer №2

If you're looking to handle Javascript objects like Dates in Next.js, you can leverage Blitz's `superjson` package. Detailed instructions can be found at https://github.com/blitz-js/superjson#using-with-nextjs:

Using with Next.js

Next.js data hooks such as getServerSideProps, getInitialProps, and getStaticProps have limitations when it comes to transmitting JavaScript objects like Dates. To overcome this issue of converting Date objects to strings, etc., Superjson proves to be a helpful solution.

Next.js SWC Plugin (experimental, v12.2 or above)

While experimental, Next.js SWC plugins offer a significant performance boost. To integrate the SuperJSON SWC plugin, install it first and include it in your next.config.js:

yarn add next-superjson-plugin
// next.config.js
module.exports = {
  experimental: {
    swcPlugins: [
      [
        'next-superjson-plugin',
        {
          excluded: [],
        },
      ],
    ],
  },
} 

Answer №3

It appears that nextJS has a preference for serializing only scalar types for optimization purposes. More information on this can be found in a GitHub thread. To work around this, you should convert your Date objects to UNIX timestamps before returning them.

// Sample data
let newsLetters = [
    {
        id: 'your-id',
        email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="12777f737b7e52776a73... [email protected]"></a>',
        createdAt: new Date()
    }
];

// Update the array
newsLetters.map(x => {
    x.createdAt = Math.floor(x.createdAt / 1000);
    return x;
})

// Utilize newsLetters
console.log(newsLetters);

Answer №4

The NextJS API Docs state that getStaticProps should return a serializable object in order for any props passed to be serialized with JSON.stringify.

This means that under the hood, boolean, number, string, and anything that passes the Lodash isPlainObject test are allowed. You can refer to the Lodash Documentation on this at https://lodash.com/docs/#isPlainObjectChecks.

In the Lodash documentation for this function, it specifies that it checks if a value is a plain object - created by the Object constructor or one with a [[Prototype]] of null.

There is a Stack Overflow post discussing the difference between an object and a plain object in JavaScript: The difference between object and plain object in JavaScript?

Expanding on @Viktor Kynchev's answer, depending on what you need from the prop, you can simply convert it to a string, number, or another type accepted by Lodash's isPlainObject method.

For example, if you have a date object provided via Prisma API like the original poster (OP), you can convert it to a string as shown below:

for (const element of newsLetters) {
  element.createdAt = element.createdAt.toString()
}

Answer №5

It's likely that you have this line of code in one of your model fields

createdAt DateTime @default(now())

Date objects cannot be serialized easily. One solution is to use the date-fns npm module

import { formatDistance } from 'date-fns'

const newsLetters = await prisma.newsLetters.findMany();
const serializedNewsLetters= newsLetters.map((newsLetter)=>({
     ...newsLetter, 
     createdAt:formatDistance(new Date(newsLetter.timestamp),new Date())
}))

This approach will provide the distance between the specified dates in a human-readable format.

Check out the formatDistance documentation for more details

Answer №6

Change your Date object into a String by following this example:


export async function getStaticProps() {
  const productDetails = await getProductDetails()

  return {
    props: {
      productDetails: {
        ...productDetails,
        createdOn: productDetails?.createdOn.toISOString(),
        updatedOn: productDetails?.updatedOn.toISOString(),
      },
    },
  }
}

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

Using arrow functions in Typescript e6 allows for the utilization of Array.groupBy

I'm attempting to transform a method into a generic method for use with arrow functions in JavaScript, but I'm struggling to determine the correct way to do so. groupBy: <Map>(predicate: (item: T) => Map[]) => Map[]; Array.prototype ...

Success Notification in ASP.net MVC after Form Submission

I am looking to implement a success alert pop-up or message after the form is submitted and action is successful. In this scenario, I want to display "successfully add": Create Action : [HttpPost] [ValidateAntiForgeryToken] public ActionResult Cr ...

Is the input in the array? How to find out?

I am currently facing an issue with a script that I have created to count array elements matching a user input. Strangely, all if statements in the script seem to be returning false. I have verified that both the array element and the input value are stri ...

Having trouble with the authorization aspect of Next Auth. The error message reads: "NextAuth.js does not support the action api with HTTP GET method

Recently, I've been encountering a puzzling error with my Next.js app authentication. It seems that I am unable to authenticate with the provided credentials. After reviewing the documentation, everything appears to be correct on my end. Additionall ...

Is there a way to verify if the object's ID within an array matches?

I am looking to compare the ID of an object with all IDs of the objects in an array. There is a button that allows me to add a dish to the orders array. If the dish does not already exist in the array, it gets added. However, if the dish already exists, I ...

Having trouble getting routing to function properly with react-router-dom

I'm currently assisting a friend with completing a React Project. I'm facing an issue while trying to set up routing using react-router-dom. The components inside the <switch> tag are not functioning properly. Below are snippets of my code: ...

Can the hasClass() function be applied to querySelectorAll() in JavaScript?

As a beginner in javascript and jquery, I recently attempted to manipulate classes using the following code snippet: if ($(".head").hasClass("collapsed")) { $(".fas").addClass("fa-chevron-down"); $(".fas&qu ...

Tips for enabling resize functionality on individual components one at a time

Check out my Codepen link for the resizable event While using Jquery UI resizable, everything is functioning correctly. However, I am now looking to have the resizable event activate one block at a time. When another block is clicked, the resizable event ...

Tips for managing the sub query in nodejs?

Developed a RESTful API in nodeJS focusing on a Post-type feature. The process involves executing two queries: 1. Initially fetching user-Id and answer details from the answers table. Upon checking the console, two user-Ids are displayed. 2. Secondly, que ...

When clearInterval is used to stop a setInterval, it will not automatically restart if reset with setInterval

I am facing an issue with a countdown timer that I have created using setInterval in JavaScript. The timer is supposed to countdown from one minute at one second intervals. However, when I click the "start" button, it starts the countdown but if I click an ...

Having four videos displayed on one webpage can cause the browser to function at a slower

I have videos that are around 30 seconds long and 15mbs. I'm wondering if it's feasible to include them on a page or if I should opt for cover images instead. I would like to use the video as a separator similar to the design showcased at Does a ...

Creating a custom loading page in Next.js 13: A step-by-step guide

Hello, I am currently working on implementing a loading page for my website to enhance the user experience during a longer loading time. I have created a simple functional component that displays a loading message and imported it into my layout.jsx file in ...

Warning: Node 125008 has reached the maximum number of listeners, indicating a potential memory leak in the EventEmitter

(node:125008) MaxListenersExceededWarning: There may be a memory leak with EventEmitter as 11 ready listeners have been added. Try using emitter.setMaxListeners() to raise the limit Can anyone provide guidance on how to increase the listener event count? ...

Tips for styling cells in a certain column of an ng-repeat table

I am currently facing an issue with a table I have created where the last column is overflowing off the page. Despite being just one line of text, it extends beyond the right edge of the page without being visible or scrollable. The table is built using th ...

Deactivate the button in the final <td> of a table generated using a loop

I have three different components [Button, AppTable, Contact]. The button component is called with a v-for loop to iterate through other items. I am trying to disable the button within the last item when there is only one generated. Below is the code for ...

How to resolve hydration error in Next.js: Issue - Server-rendered HTML content does not match the text content

What should be done when the client has additional or different information than the server? For example, reading data from localStorage and displaying it. The content is different, so why does this hydration error occur? Error: Text content does not matc ...

Causes of the error message 'TypeError: res.render is not a function'

I have set up an express application with the following code: var express = require('express'); var router = express.Router(); var passport = require('passport'); var User = require('../models/user'); var request = require(&a ...

Issue with FullPageJS: scrollOverflow feature not functioning upon click event

I am currently working on a Fullpage.js instance that needs to be initialized with a click event and then destroyed when switching to another page, and vice versa. The scrollOverflow feature works perfectly as long as the #fullpage element is not hidden up ...

Retrieve the content from paragraph elements excluding any text enclosed within span tags using the Document.querySelector method

Exploring the following element structure: <p> <span class="ts-aria-only"> Departure </span> RUH <span class="ts-aria-only">&nbsp;Riyadh</span> </p> In an attempt to extract the text RUH, it has been disc ...

Add a variety of parameters to the URL in order to make an AJAX request

I want to dynamically add values from checked checkboxes to a URL for use in an AJAX call. I only want these values to be added to the URL if the checkbox is checked. If a user checks and then unchecks, I do not want that value included in the URL. Below ...