0

I have the code (JavaScript + a bit of Html) below taken from Data Visualization with Python and JavaScript b Kyran Dale (I am a total novice where the web is concerned - a long time spent as a DBA not concerned with matters internet), but am now getting into a Masters as a mature student and I need to knuckle down and actually learn this stuff!! :-) )

JavaScript (do_student_data.js):

var studentData = [
  {name: 'Bob', id:0, 'scores':[68, 75, 76, 81]}, 
  {name: 'Bob', id:0, 'scores':[68, 75, 76, 81]}, 
  {name: 'Bob', id:0, 'scores':[68, 75, 76, 81]}, 
  {name: 'Bob', id:0, 'scores':[68, 75, 76, 81]}, 
];

function processStudentData(data, passThreshold, meritThreshold){
    passThreshold  = typeof  passThreshold !== 'undefined'?  passThreshold: 60;
    meritThreshold = typeof meritThreshold !== 'undefined'? meritThreshold: 75; 

data.forEach(function(sdata){
    var av  = sdata.scores.reduce(function(prev, current){
        return prev + current;
    },0)/sdata.scores.length;
    sdata.average = av;

    if(av > meritThreshold){
        sdata.assessment = 'Passed with merit';
    }

    if(av > passThreshold){
        sdata.assessment = 'Passed';
    }
    else{
        sdata.assessment = 'Failed';
    }

    console.log(sdata.name + "'s (:id " + sdata.id + ") final assessment is: " + sdata.assessment.toUpperCase());
    });
}

Html:

<!-- index.html -->
<!DOCTYPE html>
<meta charset = "utf-8">

<head> 
<!-- this head section has to be added otherwise a file not found :8000/favicon.ico:1 error occurs
see here https://stackoverflow.com/questions/31075893/im-getting-favicon-ico-error
-->
<link rel="shortcut icon" href="#">
</head>

<div id = 'viz'></div>
<script type = "text/javascript" src = "./do_student_data.js"></script>
<script>processStudentData(studentData)</script>

I run

python3 -m http.server

from the directory where the files are placed and then open up Chrome (recommended by Dale) and hit Ctrl-Shift-J to get the console but there' nothing there - it's empty.

I've tried putting

<div id = 'viz'>processStudentData()</div>

with and witout parentheses but still no joy!

I've also tried doing the following to no avail:

<div id = 'viz'></div> <!-- dummy div -->
<script>processStudentData(sdata)</script>    <<---- ADDED LINE!!!
<script type = "text/javascript" src = "do_student_data.js" async></script>

I have processStudentData(XXXX) both with and without studentData in place of XXXX (i.e. otherwise blank!)

I would like to know
a) how to get the code to work, and more importantly
b) the calling conventions for JavaScript within the browser like this - any references, URLs &c. gratefully received, but a quick explanation would also be appreciated. Do I need to call my code within a div or other section?

Vérace
  • 854
  • 10
  • 41
  • 3
    you've declared a function `processStudentData` but you never call this function – Thomas Sep 29 '18 at 12:18
  • OK - so how do I call it? I did say that I was a complete n00b... :-) I've tried putting
    processStudentData()
    (with and without parentheses) - but no luck!
    – Vérace Sep 29 '18 at 13:49
  • @Vérace To run code, you'll need to put it in a ` – Bergi Sep 29 '18 at 14:00
  • But it **is** in a script, isn't it? It's in do_student_data.js? Maybe an example would help me - what actual code do I write to call the processStudentData function which is inside the do_student_data.js script file which I reference at the bottom of my html file? – Vérace Sep 29 '18 at 14:04

2 Answers2

1

From the code you posted, there are couple of issues.

  • Calling the function from do_student_data.js or in script tags won't make a difference unless you build the DOM elements by yourself and append it to an already mounted DOM node.
  • You don't need a http server running if you are not receiving data from server
  • You tried to invoke a function from a script that isn't loaded yet.

Check here on how to create DOM elements dynamically using API

If you don't use any UI frameworks you need to build DOM by yourself

To print in console logs, make following changes and it should do the trick

<script src="./do_student_data.js"></script> <script type="text/javascript">processStudentData(studentData)</script>

var studentData = [
  {name: 'Bob', id:0, 'scores':[68, 75, 76, 81]}, 
  {name: 'Bob', id:0, 'scores':[68, 75, 76, 81]}, 
  {name: 'Bob', id:0, 'scores':[68, 75, 76, 81]}, 
  {name: 'Bob', id:0, 'scores':[68, 75, 76, 81]}, 
];

function processStudentData(data, passThreshold, meritThreshold){
    passThreshold  = typeof  passThreshold !== 'undefined'?  passThreshold: 60;
    meritThreshold = typeof meritThreshold !== 'undefined'? meritThreshold: 75; 

data.forEach(function(sdata){
    var av  = sdata.scores.reduce(function(prev, current){
        return prev + current;
    },0)/sdata.scores.length;
    sdata.average = av;

    if(av > meritThreshold){
        sdata.assessment = 'Passed with merit';
    }

    if(av > passThreshold){
        sdata.assessment = 'Passed';
    }
    else{
        sdata.assessment = 'Failed';
    }

    console.log(sdata.name + "'s (:id " + sdata.id + ") final assessment is: " + sdata.assessment.toUpperCase());
    });
}
<!-- index.html -->
<!DOCTYPE html>
<meta charset = "utf-8">

<head> 
<!-- this head section has to be added otherwise a file not found :8000/favicon.ico:1 error occurs
see here https://stackoverflow.com/questions/31075893/im-getting-favicon-ico-error
-->
<link rel="shortcut icon" href="#">
</head>

<div id = 'viz'></div>
<script type = "text/javascript" src = "./do_student_data.js"></script>
<script>processStudentData(studentData)</script>
Phanindra
  • 329
  • 2
  • 11
  • I put in the code exactly as you have it, but I get this: "do_student_data.js:12 Uncaught ReferenceError: data is not defined at processStudentData (do_student_data.js:12) at (index):15" Could you show me exactly how both files should be just to get console output? – Vérace Sep 29 '18 at 14:59
  • Are you invoking method like this `processStudentData(studentData)` as you have named your variable as `studentData` and not `sdata` – Phanindra Sep 29 '18 at 15:04
  • I tried with both studentData **and** sdata (sdata makes no sense - it's just the internal reference to the variable as passed in IMHO). Could you show me the whole thing with both files as you can get it working? – Vérace Sep 29 '18 at 15:05
  • I have added full working code. Let me know if you still have issue! – Phanindra Sep 29 '18 at 15:15
  • Thanks for your edit, but that's **exactly** what I had and the error is "do_student_data.js:12 Uncaught ReferenceError: data is not defined at processStudentData (do_student_data.js:12) at (index):14" - what is your do_student_data.js file in this case? – Vérace Sep 29 '18 at 15:15
  • Sorry - I'm now getting the last line - I presume there's a foreach or similar in there somewhere that's being missed? – Vérace Sep 29 '18 at 15:18
1

You don't call anywhere the function you wrote, try adding it at the end of your .js file

var studentData = [
    { name: 'Bob', id: 0, 'scores': [68, 75, 76, 81] },
    { name: 'Bob', id: 0, 'scores': [68, 75, 76, 81] },
    { name: 'Bob', id: 0, 'scores': [68, 75, 76, 81] },
    { name: 'Bob', id: 0, 'scores': [68, 75, 76, 81] },
];

function processStudentData(data, passThreshold, meritThreshold) {
    passThreshold = typeof passThreshold !== 'undefined' ? passThreshold : 60;
    meritThreshold = typeof meritThreshold !== 'undefined' ? meritThreshold : 75;

    data.forEach(function (sdata) {
        var av = sdata.scores.reduce(function (prev, current) {
            return prev + current;
        }, 0) / sdata.scores.length;
        sdata.average = av;

        if (av > meritThreshold) {
            sdata.assessment = 'Passed with merit';
        }

        if (av > passThreshold) {
            sdata.assessment = 'Passed';
        }
        else {
            sdata.assessment = 'Failed';
        }

        console.log(sdata.name + "'s (:id " + sdata.id + ") final assessment is: " + sdata.assessment.toUpperCase());
    });
}

processStudentData(studentData);
<!-- index.html -->
<!DOCTYPE html>
<meta charset = "utf-8">

<head> 
<!-- this head section has to be added otherwise a file not found :8000/favicon.ico:1 error occurs
see here https://stackoverflow.com/questions/31075893/im-getting-favicon-ico-error
-->
<link rel="shortcut icon" href="#">
</head>

<div id = 'viz'></div>
<script type = "text/javascript" src = "./do_student_data.js"></script>

Now just double click your .html file, a page opens in chrome. Open the console. Now you'll see your console.log results!

  • Salut Fabien, I put your code at the end of my .js ( console.log(sdata.name + "'s (:id " + sdata.id + ") final assessment is: " + sdata.assessment.toUpperCase()); }); } processStudentData(studentData); ) and I get the error "(do_student_data.js:12 Uncaught ReferenceError: data is not defined at processStudentData (do_student_data.js:12) at do_student_data.js:33". Can you show me **exactly** how both files should be? – Vérace Sep 29 '18 at 15:02
  • Coucou! Code snipped added, I litteraly just added the function call at the end of the .js file :) – Fabien Rajaonarison Sep 29 '18 at 15:26
  • Yes, I see and I've run the code. It looks like it's working, but I can only see one message (Bob id:0) - I can't see the others - it's telling me I have 4 user messages - this is Chrome. I'm sorry if my questions seem basic, but I'm a newbie and I'm finding it very frustrating! :-( (putain!!!). Do you know how I can see all my messages - otherwise I don't know if my code has worked! – Vérace Sep 29 '18 at 15:33
  • It's alright, you have to start somewhere ahah. You can actually see a number before the console.log that looks like **(4) Bob's (:id 0) final assessment is: PASSED**. The 4 represents the number of times a string has been output to the console. If you called your processStudentData function 2 times the number would be 8. – Fabien Rajaonarison Sep 29 '18 at 15:35
  • Yes, but I want to see the 4 messages to know that my code has worked properly! And anyway, it's confusing - message 4 should be the **last** id and not the first - non? – Vérace Sep 29 '18 at 15:37
  • Try calling your function multiple times and see what happens ;) – Fabien Rajaonarison Sep 29 '18 at 15:41
  • Again - simple question: how would I do this? I think I'll just Google how to unbundle messages - Google should know a thing or two about Chrome! :-) I'll give you a +1 for your help - thanks for that - I would give you a correct answer, but I got another one in before yours - dommage mec! :-) A+ – Vérace Sep 29 '18 at 15:45
  • Oh, I get what you're trying to do now. To make it clearer, chrome console doesn't show you all 4 outputs because they are all the EXACT same. So instead of showing 'hello world' four times it just shows '(4) hello world' – Fabien Rajaonarison Sep 29 '18 at 15:50
  • Anyway, the way (in Chrome) to see all messages is to hit Ctrl-Shift-J for console (no surprise there :-) ) and then go to the "Customise and control Dev Tools" (the three vertical dots next to the x at the top right (and confusingly NOT the "Console settings" (little gear wheel just below the x) and then within that dropdown menu, choose "Settings" and then scroll down to "Show timestamps" - HTH in future... p.s. welcome to the forum and congrats on your first post(s) (I'm dba myself normally). It would be great if we could get to the bottom of this (et merci encore!) – Vérace Sep 30 '18 at 07:51
  • Nice to hear you found the solution to your problem ! (de rien, on s'entraide entre devs) – Fabien Rajaonarison Sep 30 '18 at 13:03