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

Ways to prevent false activation of functions due to changes and clicks

I have a text box and a clear button. When the user inputs something in the text box and then clicks out of it, a function called 'validate()' is triggered to perform an action. However, when I click the clear button instead and trigger another f ...

What is the best way to utilize node exec in synchronous mode?

I have a scenario where I need to run exec synchronously. Is there an alternative method to achieve this without using the deprecated execSync library? Can bluebird promises be used for this purpose? for (var i = 0; i < testCasesLength; i++) { va ...

Ways to determine if prototype methods vary

Is there a technique to verify if functions are distinct despite originating from the same prototype? I'm inquiring because I want to save functions in an array, and when attempting to delete one, it removes all functions due to sharing prototypes. ...

Discovering descendant div elements

I've been conducting some research, but I'm struggling to find a specific answer for this. Here is the HTML code snippet: <div class="collapsingHeader"> <div class="listItemWrapper"> <div class="itemWrapper"> ...

Guide to substituting the index value with the user's specific choice

Let's simplify this. Suppose I have a list in my ng-repeat 1. A & index[0]<br> 2. B & index[1]<br> 3. C & index[2]<br> 4. D & index[3]<br><br> and there is an input field where the user can priorit ...

javascript function not being invoked

Currently, I have incorporated the following HTML <html> <head> <Title>EBAY Search</title> </head> <script language="JavaScript" src="ajaxlib.js"></script> <body> Click here & ...

The withAuth module is not exported in the next-auth package for Next.js

I'm currently exploring how to implement a middleware on the /admin route in next.js. In my file "_middleware.js", I have the following code snippet: import { withAuth } from "next-auth/middleware"; export default withAuth({ callbacks: { au ...

Show different components depending on immediate modifications and complete or incomplete data entry in Vue.js

I am trying to create a simple form with a search bar and two buttons. The goal is for the fill button to be visible only when there is text in the input, and for the empty button to show when the input is empty. I want the buttons to dynamically display o ...

The ng-bind directive is functional when used with a textarea element, but it does not work with

Recently diving into the world of angularjs, I stumbled upon ng-bind and its interesting functionality when used as a directive for textarea: <input type="text" ng-model="review.start"/> <textarea ng-bind="review.start"> </textarea> I ...

Using object bracket notation in TypeScript to retrieve values from props with the help of string interpolation

I encountered an issue in my code while attempting to utilize a variable within my TSX component. This problem arises due to the dynamic props being passed into the component, which are always a string that matches one of four keys in the "characters" obje ...

The browser is not showing JavaScript alerts and prompts when they are called inside a function

/*I am attempting to run a color guessing game in my browser, but when I try opening the code in Chrome, it doesn't work. Any suggestions or ideas would be greatly appreciated.*/ var colors = ["Aqua", "Black", "Blue", "Brown", "Coral", " ...

How can one discern the most effective method to identify JavaScript code that alters particular HTML content on a webpage?

On my website, I have a <p> tag and I am interested in knowing which JavaScript function is responsible for adding text inside this element. Is there a special method in Chrome to add a listener on this tag and pinpoint the script that writes to it ...

Deciding whether an altered image has been successfully loaded

Currently, I am stuck on a minor point while creating a small gallery using jQuery. The code snippet looks like this: <script type="text/javascript> $(document).ready(function(){ $('#thumb1').click(function(){ $('#fullimage ...

Easily fetching data with AJAX through jQuery

Completely new to using jQuery and AJAX, I attempted the code below for a simple http get request: <html> <head> </head> <body> <script src = "jquery-2.1.4.js"></script> <script src = "app.js"></script& ...

What is the correct method for launching a modal window in wagtail-admin?

I am currently working on enhancing my wagtail-admin interface, but I have hit a roadblock when trying to open a modal window. While I could create a div with a close button, I believe there must be a more appropriate method for achieving this. It seems th ...

What is the best way to transfer a file input to an azure blob in a Next.js environment?

I'm currently following a tutorial on YouTube, you can find it here: https://youtu.be/dTFXufTgfOE. The GitHub repository for this tutorial is located at: https://github.com/dejwid/ecommerce-admin The original tutorial uses AWS in upload.js, but I wan ...

The API endpoint code functions perfectly in Express, but encounters an error when integrated into Next.js

Express Code: app.get('/', async (req, res) => { const devices = await gsmarena.catalog.getBrand("apple-phones-48"); const name = devices.map((device) => device.name); res.json(name); }) Nextjs Code: import {gsmarena} ...

Embed Custom Component Into NextJS Link

Issue: I am facing an issue with rendering a custom child component inside Next's <Link> component. I have a component that is supposed to redirect users to a new page on click, and I want to use the <Link> component provided by Next.js f ...

What could be causing the 500 response code when making a request to the NextJS API route within the app directory?

Every time I attempt to access my API route, a 500 Internal Server Error code is returned The origin of the request export const fetchSuggestion = async () => { const response = await fetch('/api/getSuggestion', { cache: 'no-store&ap ...

How can I display several custom markers that are constantly updating on a Google map with MySQL and PHP?

Currently, I am using the following code to generate markers on a Google map by retrieving data from a database. However, the issue I am facing is that it only generates one marker instead of all the markers stored in the database. & ...