Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getServerSideProps and mysql (RowDataPacket)

I'd like to do server side rendering with Next.js using the getServerSideProps method like explained in the docs.

The data should come from a database, so I'm using the mysql package. This results in the following error:

Error serializing `.assertions[0]` returned from `getServerSideProps` in "/assertion". Reason: `object` ("[object Object]") cannot be serialized as JSON. Please only return JSON serializable data types.

I think the reason for this is, because the query method from mysql returns special objects (RowDataPacket). The result that I'd like to pass to getServerSideProps looks like this when logged:

[ RowDataPacket { id: 1, title: 'Test' } ]

I can fix this error by wrapping the result with JSON.parse(JSON.stringify(result)) but this seems very odd to me.

So, my simple question is: How to use mysql.query and getServerSideProps correctly?

Or might this be an issue that should be addressed by Next.js?

Thank you

like image 461
K. D. Avatar asked Apr 13 '20 13:04

K. D.


1 Answers

I've run into this issue myself. When I had the issue it wasn't related to MySQL. The problem is getServerSideProps() expects you to return a "JSON serializable data type" which basically means a Plain ol' JavaScript Object (POJO).

To fix it, simply create a new POJO to return. A few ways you can go are:

// using spread operator to create new object
const plainData = {
  ...queryResult
}

// recreating the object with plucked props
const plainData = {
  title: queryResult.title,
  content: queryResult.content
}

// data conversion (wax-on wax-off)
const plainData = JSON.parse(JSON.stringify(queryResult))

Your specific data is in an array so your simplest solution is the wax-on wax-off since it will support arrays. Otherwise you've got to map over it.

why tho?

You can see your object has RowDataPacket attached to it. This means it's an instance of RowDataPacket and NextJS doesn't allow any instances unless it strictly equals the Object.prototype (see related code)

This seems weird, but they have already described why it's necessary in a Github Issue. TL;DR dates cause issues client-side when the page hydrates.

like image 100
cmfolio Avatar answered Nov 17 '22 08:11

cmfolio