如何将 JavaScript 对象/数组发送到前端 - node.js 应用程序

Posted

技术标签:

【中文标题】如何将 JavaScript 对象/数组发送到前端 - node.js 应用程序【英文标题】:How to send JavaScript object/array to front-end - node.js app 【发布时间】:2019-10-03 21:42:36 【问题描述】:

我正在尝试将数据发送到我的应用程序的前端以创建图表。我将数组附加到响应对象中,但这不起作用,尽管我可以使用前端响应对象中发送的用户值。

var scoreQuery = "SELECT q1, q2, q3, q4, q5, q6, q7, q8, q1, q2, q3, q4 FROM table WHERE id = user.id";

var scoreArray;

module.exports = function(app, passport)

    app.get('/profile', isLoggedIn, function (req, res) 
        connection.query(scoreQuery, function (err, result, fields) 
                if (err) throw err;
                getData(result);
                console.log(scoreArray);
            , res.render('profile.ejs', 
                user:req.user,
                data: scoreArray
            )
        );


    );

;

function getData(result)
    Object.keys(result).forEach(function(key) 
        const values = result[key];
        scoreArray = Object.values(values);
    );
);

下面是我创建图表的 public/javascripts/scripts.js 文件。

/*Scripts*/

var quizCategory1 = data.scoreArray.slice(0,7); 
var quizCategory2 = data.scoreArray.slice(8,11);

var cat1Total = totalScore(category1);
var cat2Total = totalScore(category2);


function totalScore(categoryScore)
    return categoryScore = scoreArray.reduce((accum,scoreArray) =>
        
            const splitValues = scoreArray.split('/');

            return 
                score:accum.score + parseInt(splitValues[0]),
                maxScore:accum.maxScore + parseInt(splitValues[1]),
            
        ,score:0,maxScore:0
    );



var ctx = document.getElementById("myChart").getContext('2d');
var barTotalCategoryScores = [cat1Total.score, cat2Total.score];

var labels = ["Java & Design", "Build & Versioning"];

var myChart = new Chart(ctx, 
    type: 'bar',
    data: 
        labels: labels,
        datasets: barTotalCategoryScores
          
    
);

每当用户登录时 scoreArray 就会打印到控制台,因此 sql 查询和 getData() 函数正在工作。但是当我尝试在我的 scripts.js 文件中使用 data.scoreArray 时,它不起作用。

【问题讨论】:

【参考方案1】:

添加新路线:

app.get('/profile/:id', (req,res) => 
    // your_array = query DB with param id (req.params.id) store in your array
    res.status(200).json(data: <your_array>)
)

然后在您的客户端上对 /profile/:id (https://developer.mozilla.org/fr/docs/Web/API/XMLHttpRequest) 进行 GET 查询 页面加载时(window.onload)


对于 mysql,您应该使用:

http://docs.sequelizejs.com/ http://docs.sequelizejs.com/manual/getting-started.html#installing http://docs.sequelizejs.com/manual/dialects.html#mysql http://docs.sequelizejs.com/manual/querying.html

【讨论】:

感谢您的帮助 :) 您将如何以及在何处实现客户端的 get 查询?我是初学者。 另外,我真的不明白这个 // your_array = query DB with param id (req.params.id) store in your array 是我在顶部的 DB 查询,var scoreQuery ? :id 指的是什么? you_array 这是您的客户端所需的数据 (scoreArray) 对于客户端检查:***.com/questions/1973140/… 对不起,我真的不明白这是什么意思“(req.params.id) store in your array”。 req 是你的请求对象,包含参数 /:id (express)【参考方案2】:

服务器:


// ... your routes


// + new route
app.get('/profile/:id', (req,res) => 
     let id = req.params.id // e.g /profile/3 -> req.params.id = 3
     let scoreArray;

     // your query (it's very bad to set param in your query like this (injection SQL) )
     let scoreQuery = `SELECT q1, q2, q3, q4, q5, q6, q7, q8, q1, q2, q3, q4 FROM 
     table WHERE id = $id`;  // `... $foo` => https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Litt%C3%A9raux_gabarits

     connection.query(scoreQuery, function (err, result, fields) 
                if (err) throw err;
                getData(result);
                console.log(scoreArray);
             , res.status(200).json(
                user:req.user,
                data: scoreArray
            )
        );
 )

// ... your method

function getData(result)
    Object.keys(result).forEach(function(key) 
        const values = result[key];
        scoreArray = Object.values(values);
    );
);

客户:

/* code to get data
 let id_test = 1;

  fetch(`http://localhost:<your_node_server_port>/profil/$id_test`)
  .then(response => response.json())
  .then(json => console.log(json)) // return profil for id 1
*/

// e.g page is loaded
window.onload = () => 
  let id_test = 1;

  fetch(`http://localhost:<your_node_server_port>/profil/$id_test`)
  .then(response => response.json())
  .then(json => console.log(json)) // return profil for id 1

【讨论】:

【参考方案3】:

感谢一百万 Sylvain,您的解释让我走上了正轨。我做了以下...

//routes.js

    app.get('/profile',  function (req, res) 
        let id = req.user.id;
        getData(id, function (score) 
            res.status(200).render('profile.ejs',user: req.user, score)
        );
    );

我将我的 sql 语句放在 getData() 函数中,并在我的 sql 语句中使用 '?' 代替 id 并将 id 参数作为值发送到查询方法中。这已经奏效了,我现在可以使用 &lt;?= score.cat1Total.score ?&gt; 获取客户端 ejs 文件中的分数对象。

我现在的问题仍然是尝试在我的 public/javascripts/scripts.js 文件中使用 score.cat1Total.score 并且它是未定义的......我不确定如何正确实现您的 window.onload() 方法

// /public/javascripts/scripts.js 

/* code to get data?
window.onload = () => 
  fetch(`http://localhost:8080/profile)
  .then(response => response.json())
  .then(json => console.log(json)) 

*/

var ctx = document.getElementById("myChart").getContext('2d');

//This is where I am trying to get score objects values. 
var barTotalCategoryScores = [score.cat1Total.score, cat2Total.score];

var labels = ["Java & Design", "Build & Versioning"];

var myChart = new Chart(ctx, 
    type: 'bar',
    data: 
        labels: labels,
        datasets: barTotalCategoryScores
          
    
);

以下仅供参考是我在路由中使用的getData(id, callback) 方法

// routes.js

function getData(id, callback) 

    let scoreQuery = "SELECT c1q1, c1q2, c1q3, c1q4, c1q5, c1q6, c1q7, c1q8, c2q1, c2q2, c2q3, c2q4 FROM nodejs_login.assessment_score AS a JOIN nodejs_login.users as u ON a.respondent_id = u.user_respondent_id WHERE a.respondent_id = ?";

    connection.query(scoreQuery, [id],function (err, result) 
        if (err) throw err;

        Object.keys(result).forEach(function(key) 
            let values = result[key];
            let scoreArray = Object.values(values);

            let category1 = scoreArray.slice(0,7);
            let category2 = scoreArray.slice(8,11);

            //parsing and accumlating each category score
            var cat1Total = totalScore(category1);
            var cat2Total = totalScore(category2);


            //function to parse the strings into numbers and accumulate them
            function totalScore(categoryScore)
                return categoryScore.reduce((accum,scoreArray) =>
                    
                        const splitValues = scoreArray.split('/');
                        return 
                            score:accum.score + parseInt(splitValues[0]),
                            maxScore:accum.maxScore + parseInt(splitValues[1]),
                        
                    ,score:0,maxScore:0
                );
            
            let categories = cat1Total, cat2Total;

            callback(categories);

        );
    )

【讨论】:

以上是关于如何将 JavaScript 对象/数组发送到前端 - node.js 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

SignalR如何将javascript对象从一个客户端发送到另一个客户端

如何将数据从对象传递到javascript中的新数组?

如何在 Javascript 中将 Django 对象作为参数发送?

如何以json的格式发送到前端

将 Javascript 数组与 Java 列表匹配

前端每日一题 02在Javascript中什么是伪数组?如何将伪数组转化为标准数组?