简体   繁体   中英

TypeError: Converting circular structure to JSON when getting data from mysql DB

I'm following an angular-nodeJS tutorial and I'm trying to recover data from a MySQL database. Here's my db creation script:

CREATE DATABASE ng_games_db;
USE ng_games_db;

CREATE TABLE games (

    id INT (11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(180),
    description TEXT(255),
    image VARCHAR(200),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

);

My db connection works cause I can add entries to my only table from my app. However, when I try to get the data with this method:

public async list (req : Request, res : Response) : Promise<void> {

    const games = await pool.query('SELECT * FROM games');
    res.json(games);

}

I get the following error:

(node:5828) UnhandledPromiseRejectionWarning: TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Query'
|     property '_timer' -> object with constructor 'Timer'
--- property '_object' closes the circle
at JSON.stringify (<anonymous>)
at stringify (C:\Users\Dave\Documents\angular-mysql-crud\server\node_modules\express\lib\response.js:1123:12)
at ServerResponse.json (C:\Users\Dave\Documents\angular-mysql-crud\server\node_modules\express\lib\response.js:260:14)
at C:\Users\Dave\Documents\angular-mysql-crud\server\build\controllers\gamesController.js:23:17
at Generator.next (<anonymous>)
at fulfilled (C:\Users\Dave\Documents\angular-mysql-crud\server\build\controllers\gamesController.js:5:58)
at processTicksAndRejections (internal/process/task_queues.js:93:5)

I've been searching the internet for a while trying to fix it but I've had no luck so far.

EDIT: Here is a library I've used before that might work for your situation:

https://www.npmjs.com/package/flatted

JSON.stringify doesn't handle circular references very well, like other serializers might pass a reference, stringify() crashes. You can try this, which will remove circular references:

const getCircularReplacer = () => {
  const seen = new WeakSet();
  return (key, value) => {
    if (typeof value === "object" && value !== null) {
      if (seen.has(value)) {
        return;
      }
      seen.add(value);
    }
    return value;
  };
};

JSON.stringify(games, getCircularReplacer());
// {"otherData":123}

Here is a link where the code snippet came from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value

In the footnotes of the link above, there is also mention of cycle.js which handles circular references. https://github.com/douglascrockford/JSON-js/blob/master/cycle.js

Ultimately, you need to find a JSON serializer/ deserializer that is capable of decoding these references.

FOR PEOPLE STILL HAVING ISSUES:

For those who still have an issue with this after adding the flatted package, you need to add this line in after you create your database pool: pool.query = util.promisify(pool.query); - source: https://mhagemann.medium.com/create-a-mysql-database-middleware-with-node-js-8-and-async-await-6984a09d49f4

If you are using typescript it will complain but simply add // @ts-ignore above it and you should be fine.

You will now be able to make mysql select queries using try/catch and async/await!!

This command works fine for your problem:

pool.query ('SELECT * FROM games', function (err, rows) {res.send (rows);}); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM