I am currently doing CS50. And i feel a little lost with javascript, i don't know the best way to do things or to write "correct code". I feel that in C and in Python, the lines to do things were more clear. (Don't repeate code, make it legible, etc) In javascript, we can do things in many ways and i don't know what it's the correct.
For example i spent a few days on trivia, a problem that ask us to make buttons that turn red if the button is the incorrect answer and green if the answer is correct, i know that it's a good practice to leave all the javascript in one file different from the html, first i only use onclick in html to call a function that i implemented in the js file then i tried to change it to don't have any js code in the html page.
So i wanted to remove the onclick call, so, i put and addEventListener to the javascript on load and do all the functions there, with this, i want to check if the innerHtml of a button it's the same from the correct answer, but this code doesn't work, i think this code is the correct version because is really checking if the answer is correct
window.addEventListener("load", function () {
//Declaring first function
function checkAnswer(event) {
var buttonPressed = event.Target;
if (buttonPressed.innerHTML == 'Uruguay')
{
buttonPressed.style.background = "green";
}
else:
{
buttonPressed.style.background = "red";
}
var buttons = document.querySelectorAll('button');
buttons.forEach(b => b.addEventListener("click", checkAnswer(event)));
}
Because i was having trouble with this to function i ask a friend who uses javascript to look at it, and he say to me that there is an easy way, id all the buttons by correct or incorrect and if the user click the correct execute a function attached to that button to color the button green and if its red execute another:
const correctButton = document.getElementById("correctButton");
const Incorrectbuttons = document.querySelectorAll("#Incorrectbutton");
bcorrectButton.addEventListener("click", function(){
correctButton.style.background = "green";
});
Incorrectbuttons.forEach(btn => {
btn.addEventListener("click", function(){
btn.style.background = "red";
});
})
I feel that this code cheat because it actually don't check if the button is correct, if an user changes the inner html of the word in his browser, the button still turned green, in my code, i think that if the user change the inner html it wont change because the innerHtml don't match the "key".
I don't know if i am viewing it wrong becaused i am attached to other forms of thinking with other languages and i can do things "directly" without logic on javascript or my first function is completly wrong. Thanks!
Just to show you the beauty of a language as JavaScript - here's two possible approaches (out of many, really), one simple, and the other a little bit more advanced with dynamic templates generation - all out of some data model predefined in code:
1. Simpler solution:
Use
data-*
attribute on your parent element to store the correct answer string.Simply place your buttons into HTML and assign the correct answer value into the parent element
data-answer
attribute:As you can see above, you're not polluting your JavaScript code logic with strings, and that code can work for an infinite number of trivia ("Multiple choice") questions and buttons.
2. Advanced solution
Keep in mind - data!
So how would you structure your data for the Part 1 (and even Part 2 "Free response") of the CS50 Lab? You have multiple buttons (therefore think of it as an Array) and you have only one correct answer.
And you also have types (currently two: Multiple choices and Free Response) therefore
type
,question
,answers
,correct
can all be properties of each Object item inside thetrivia
Array.Such can be modelled like:
given the above you can iterate your
trivia
Array and generate HTML.If the currently iterating trivia item
type
is"multiple"
- generate<h3>
and your buttons.If the currently iterating trivia item
type
is"free"
- generate<h3>
, an<input type="text">
, and a button.Given the above you can have as many trivia questions as you like.
And in the future you can expand the above data for other interesting
type
s.To generate your buttons all you need to do is iterate the
data.answers
like:Regarding security / hacks
You're not in the phase to worry about security at this stage, for this Lab task. But it's nice you have that always in mind because it's extremely important!
Since the code (HTML, JS, Network requests, etc) that arrives to the browser can be spoofed or reverse-engeneered (like in the above Example 1. has the answers hardcoded in HTML; and Example 2. has them right in JS), in order to not allow a user to see the correct answers the proper approach would be to have the correct answers stored somewhere on your server (not visible to the user). Send the user selected answer to the server and check on server-side the correctness. Than the server should only respond to the browser with a response (i.e:
"correct"
/"wrong"
) so that the user interface can advance to the next question or give a final overall score. Even than, the server should never trust the user! Therefore you should implement a sort of user session using browser+backend technologies like i.e: a session cookie, and check if the data that arrives from the user matches the state in the database for that specific user (current question, correct questions count, timestamp, etc etc).Not a topic or problem that has to be solved at this stage in the CS50 Lab. But if you want - nobody stops you to explore and implement a more robust and secure solution on your own!