1

I am trying to build a webapp which renders dynamic charts based on JSON passed from node to client side.

However I am not able to access json variable inside <script>. I have tested JSON object using

console.log(<%= data %>) 

it is appearing there.

My Node code looks like:

let ltlasJSON = JSON.parse(ltlasData);

app.get("/results", function(req, res){
    var query = req.query.postalCode;
    var url = "http://api.postcodes.io/postcodes/" + query;

    request(url, function(error, response, body){
        if(!error && response.statusCode == 200){
            var data = JSON.parse(body);
            var adminDistrict = data["result"]["codes"]["admin_district"];
            var filtered = ltlasJSON.filter(a=>a.areaCode==adminDistrict);
            res.render("results", {data: filtered});
        }
    }
    );    
});

results.ejs:

<<!DOCTYPE html>
    <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
    <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
    <!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
    <!--[if gt IE 8]><!-->
    <html class="no-js">
    <!--<![endif]-->

    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Engliand Covid-19 </title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="style.css">
        <!-- Plotly.js -->
        <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
    </head>

    <body>
        <!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->


    <h1>Results Page</h1>


    <script>
    var specimenDate = <%= data.areaCode %>
    var cases = <%= data.dailyLabConfirmedCases %>
    var data1 = [
            {
                x: specimenDate,
                y: cases,
                type: 'bar'
            }
        ];
        Plotly.newPlot('myDiv', data);
    </script>
</body>

</html>

I am new to node and ejs. End goal is to pass array of JSON (two fields) in x and y variable of plotly object.

enter image description here

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Bhavesh Ghodasara
  • 1,981
  • 2
  • 15
  • 29

1 Answers1

1

I see two issues here:

1) You are passing the data incorrectly to the frontend javascript. <%= is always wrong because it encodes HTML entities, but we are in a JS script tag and not in regular HTML. Instead, you want to pass it as JSON using JSON.stringify, and use <%- to prevent HTML-encoding:

var specimenDate = <%- JSON.stringify(data.areaCode) %>

This still has two issues though: Firstly, JSON.stringify(undefined) will produce undefined (and not a string) which becomes an empty output after <%-, so you will get a syntax error in case the value was undefined. Secondly, a string containing </script> will escape the script block and wreak havoc. I'd recommend using something like devalue instead of JSON.stringify.

2) You are accessing data.areaCode, but I see that data actually comes from filtered, and filtered is the result of an Array.prototype.filter call, which returns an array of all matching elements. Yet, you are accessing the areaCode property as if data was directly one of the matching elements, not an array of all matching elements.

If it is intended that you have an array there, you have to loop over its entries, or access one directly, for example data[0].areaCode (but also you have to make sure data[0] is always existing).

If this is not intended, then you just used the wrong array method. You can use Array.prototype.find to return the first match or undefined otherwise.

Example:

const db = [
  { areaCode: 1, text: 'A' },
  { areaCode: 2, text: 'B' },
  { areaCode: 2, text: 'C' }
]

console.log(db.filter(el => el.areaCode === 1)) // [{ areaCode: 1, text: 'A' }]
console.log(db.filter(el => el.areaCode === 2)) // [{ areaCode: 2, text: 'B' },
                                                //  { areaCode: 2, text: 'C' }]
console.log(db.filter(el => el.areaCode === 3)) // []

console.log(db.find(el => el.areaCode === 1)) // { areaCode: 1, text: 'A' }
console.log(db.find(el => el.areaCode === 2)) // { areaCode: 2, text: 'B' }
console.log(db.find(el => el.areaCode === 3)) // undefined
CherryDT
  • 25,571
  • 5
  • 49
  • 74