首页 > 解决方案 > 如何将带有来自 MySQL('Concat')的数组的 JSON 对象嵌入到 NodeJS 中的 EJS 文件中?

问题描述

出于测试目的,我在 demo.js 中创建了一个 JSON 对象,它应该集成到 ejs 模板中。

如果我这样做,在 ejs 页面中一切正常。但我创建了 JSON 对象 dyn。来自 SQL 查询(见下文)。

这是我的设置:

演示.js

function gameData() {

    return {
        id: 13,
        round: 1,
        user: [{
            id: 4711,
            player_id: 1,
            name: "John",
            value: 3,
            active: 1
        }, {
            id: 4712,
            player_id: 2,
            name: "Phil",
            value: 3,
            active: 0
        }]
    }
}

module.exports = {
    gameData: gameData
}

应用程序.js

let gameDemo = require('./demo');

app.get('/game', (req, res) => {
    res.render('pages/game', {
        utils: gameDemo
    });
})

ejs网站

<% utils.gameData().user.forEach(function(element, index, item){ %>
    <%= element.player_id %>
<% }); %>

在这里,我创建了一个 MySQL 数据库 (5.7) 连接并获取 JSON 对象作为结果。不幸的是,它不适用于那个。

应用程序.js

app.get('/game', (req, res) => {

    ...

    db.getConnection((error, connection) => {
        
        let sqlQuery = `SELECT
                            CONCAT("{",
                            CONCAT("id:" , g.id, ","),
                            CONCAT("round:" , g.round, ","),
                            CONCAT("user:", "[",
                                GROUP_CONCAT(
                                CONCAT("{"),
                                    CONCAT("id:" , gd.id, ","),
                                    CONCAT("player_id:" , gd.player_id, ","),
                                    CONCAT("name:" , gd.name, ","),
                                    CONCAT("value:" , gd.value, ","),
                                    CONCAT("active:" , gd.active, ","),
                                CONCAT("}")
                                )
                            ,"]")
                            ,"}")
                        AS json FROM game_data gd
                            INNER JOIN games g
                            ON g.game_id = gd.game_id
                        WHERE gd.game_id = '235816ab-2ad8-41b2-8375-d980e207e43f'`

        connection.query(sqlQuery, (err,row, fields) => { 
        
            res.render('pages/game', {
                utils: row[0].json
            });

        })
        connection.release();

    })
     
 })

索引.ejs

<% utils.gameData().user.forEach(function(element, index, item){ %>
     <%= element.player_id %>
<% }); %>

我收到错误:“无法读取未定义的属性 'forEach'”

如果我调用<% = utils %>ejs,我会得到 JSON 对象作为字符串。

然后我尝试JSON.parse(row[0].json)得到SyntaxError: Unexpected token t in JSON at JSON.parse () 的位置 1

JSON.parse(result)显示错误undefined:1 [object Object]

然后我尝试了

app.get('/game', (req, res) => {

    ...

    db.getConnection((error, connection) => {
        
        let sqlQuery = `SELECT
                            CONCAT("{",
                            CONCAT("id:" , g.id, ","),
                            CONCAT("round:" , g.round, ","),
                            CONCAT("user:", "[",
                                GROUP_CONCAT(
                                CONCAT("{"),
                                    CONCAT("id:" , gd.id, ","),
                                    CONCAT("player_id:" , gd.player_id, ","),
                                    CONCAT("name:" , gd.name, ","),
                                    CONCAT("value:" , gd.value, ","),
                                    CONCAT("active:" , gd.active, ","),
                                CONCAT("}")
                                )
                            ,"]")
                            ,"}")
                        AS json FROM game_data gd
                            INNER JOIN games g
                            ON g.game_id = gd.game_id
                        WHERE gd.game_id = '235816ab-2ad8-41b2-8375-d980e207e43f'`

        connection.query(sqlQuery, (err, result) => { 

            res.render('pages/game', {
                utils: result[0].json // JSON Object
            });

        })
        connection.release();

    })
     
 })

在 ejs 文件将得到一个 json 对象

console.log(<%= utils %>) // JSON Object in console OK
console.log(typeof <%= utils %>) // Object

如果我在 javascript 区域中创建一个变量,let obj = <%= utils %>;我可以完全访问数据。

但是,我如何从 ejs 的数组中获取任何值?

标签: mysqlnode.jsjsonejs

解决方案


我发现,如果查询有“大”结果(超过 10 个键/值),键/值对有时会有换行符。请参阅用户密钥 9。没有可识别的错误模式。

结果的奇怪行为。该错误仅在用户数组中的对象中发生一次。但并非每个对象都受到影响。

从 sql 结果中提取:

{
    "id": 13,
    "round": 1,
    "user": [{
        "1": 8,
        "2": 9,
        "3": 10,
        "4": 0,
    "5": 8,
    "6": 9,
    "7": 10,
    "8": 0,
    "9": 
    8,
    "10": 9,
    "11": 10,
    "12": 0,
    "13": 8,
    "14": 9,
    "15": 10
    }]
}

解决方案

我将 SQL 查询放在双引号中并将其转义。将 SQL 结果(字符串类型)解析为一个对象,就是这样。

db.getConnection((error, connection) => {

    let sqlQuery = `SELECT
      CONCAT("{",
        CONCAT("\\"id\\":" , g.id, ","),
        CONCAT("\\"round\\":" , g.round, ","),
        CONCAT("\\"user\\":", "[",
            GROUP_CONCAT(
              CONCAT("{"),
                  CONCAT("\\"id\\":" , gd.id, ","),
                  CONCAT("\\"player_id\\":" , gd.player_id, ","),
                  CONCAT("\\"name\\":" , gd.name, ","),
                  CONCAT("\\"value\\":" , gd.value, ","),
                  CONCAT("\\"active\\":" , gd.active, ","),
              CONCAT("}")
            )
        ,"]")
      ,"}")
  AS json FROM game_data gd
  INNER JOIN games g ON g.game_id = gd.game_id
  WHERE gd.game_id = '235816ab-2ad8-41b2-8375-d980e207e43f'`

    connection.query(sqlQuery, (err, result) => {

        let stringRes = result[0].json
        let obj = JSON.parse(stringRes)

        res.render('pages/game', {
            gamedata: obj
        });

    })
    connection.release();

})

现在我可以完全访问 ejs 文件中的 JSON-Object。

对象内的值:<%= gamedata.id %>

用户数组中的值:<%= gamedata.user[0].player_id %>

用户数组中每个对象的值:

<% for (var i = 0, l = gamedata.user.length; i < l; i++) {
  var obj = gamedata.user[i];
%>
  <option value="<%= i %>"><%= obj.player_id %></option>
<% } %>

推荐阅读