Instructor: Alright, so here goes my solution
to an expert level of our small quiz app.
So at first take the code that we just wrote
and copy it down there.
So I'm going to comment it out and copy it.
And paste it down here.
So this is the starting point to now code
the expert level of the quiz.
So let's take a look at our first task here.
So after we display the result,
we then want to display the next random question.
So let's do that and simply write a function.
And what this function is going to do,
it's going to do all of this game logic here
so that we can call it over and over again.
So let's call this function nextQuestion.
So function nextQuestion,
and of course it doesn't need any parameters.
And now let's put into the inside
and then of course we need to call it nextQuestion.
Okay, so right no this is actually exactly the same thing
that we had before, so nothing different is going to happen.
Because now we need to also call
this function here in the end.
So imagine we execute this function here
and then after all of this is done,
so after we selected our question,
displayed it, and checked the answer,
we simply want to call this again.
So very simple.
We simply write nextQuestion again.
Actually, this part here we only need to do once
so the array for questions is always going to be the same.
So nothing changes there.
Now remember the problem that I described
which is that right now, if we would call this app like this
then we would have no way to actually ever stop this quiz.
Because each time that we hit the cancel button
on our prompt window, it simply opens a new window
and then there's no way to really stop this.
So we have to have a way to stop the game
and that is by writing exit into the prompt window
instead of writing the number for the correct answer.
So let's say that we only want to call this next question
if the input from the user is not exit.
So we say if the answer is different from exit,
only then we want to call the next question again.
So this makes sense, right?
And actually we also want to only do this one
if the user doesn't choose to exit the game.
So we only need to check if the answer is correct
if the game continues.
So if it's not an exit.
Alright, now before we can actually try this out
in the browser, there's still one issue with this
and that is that up here, we converted the answer
to a number, but here, down here we want to check
if the answer is exit, so if it's this string.
And that means that we actually do not want to convert
the answer to a number here at this point
because then we can no longer perform this check here
because at this point the answer will no longer be
an exit string, never.
Okay, so we need to take this out from here and move it
so we are going to move it to here.
So parseInt this answer.
So we're simply moving the parseInt function down here
which is where we actually want a number.
So we want to pass a number into the check answer method.
And so now, everything should be set
for this to work correctly.
So let's try this out.
So the name is Jonas, and alright.
So you see we have a next question
and we have a new prompt window here.
So what does best describe coding, it's fun.
Correct answer and the next question.
So great, it's working just fine.
So the first step, or the first two steps actually,
are completed with this.
Now remember we need to write exit
if we want to exit from this game.
So let's try this out so to see if this also works.
And yes, it worked.
So our code is complete at this point.
Remember all of the stuff we wanted to do again,
each time after the user gave an input,
we simply wrote it in a function, called it at the beginning
and then called it each time
that we want to continue the game.
So each time that the user didn't write,
exit into the prompt window.
So this was the easier part of this challenge,
so let's now talk about keeping the score of the user.
And as I mentioned before,
I am going to use the power of closures here in this case.
So let's see how.
My solution is to write a function here
which is going to keep the score and to update it
when the answer that the user gave is correct.
This is going to be like a nice container
where I can keep everything that is related to the score.
So the score itself and the function to update it
instead of having global variables and variable mutations
all over the place in our code.
So let's just see how it's going to work.
So functions and very simply score.
And in here I'm going to create a variable called score.
Let's say sc for the short version of score
and zero, just because I don't want to repeat
the same name here.
And this function here is going to return another function
and what this function does is to increase the score
if the answer is correct and then return it.
So we actually need a parameter here
which says if it's correct.
So it's going to be a true or false value.
And then if the answer was correct, then update the score.
And we know there's a nice operator for that
and it's this one, so it's the same one we always use
in for loops.
So this simply adds one to the score.
And then either way, if it's either correct or true,
it's going to always return the score.
And so this way, everything that I need about the scores
is here in this function that this closure returns.
Now all I have to do is to call this function
and store it because it returns another function
and so I want to keep that function in this variable.
And I'm going to call it keepScore, so score,
and call it, and that's it.
So what's going to happen?
Remember what closures are.
So we call the score function, it defines as variable,
and then we return this function here
and it's going to be attached to this variable.
Now thanks to closures,
we always keep access to the variables
that the other function defines.
So this means that this score variable here
will always be accessible by this keep score function here.
So this is exactly what we did in the other exercises
in the closure lecture.
So the exact same thing, but now it's applied
to this problem, to this application.
At this particular point,
maybe this doesn't make so much sense to you
so why I used it this way, so let's now see it in action
and it's going to work like this.
So we check our answer here, so here actually,
so we check our answer
and in here we can then call this function
that I just defined to update the score
if the answer is correct.
In order to be able to do that,
we need to actually pass this function
into this method here.
So we're going to make use of the concept
that we can pass functions around,
because they're first class objects in JavaScript,
so first class functions.
So the checkAnswer, the method is going to be called here,
so checkAnswer, so we're not only going to be passing
the answer in here, but also the keepScore variable.
So keepScore, which is the variable
that contains the function
and the closure which keeps track of the score, remember.
And so now in here we also need to set the parameter
so answer and call back.
Let's call it like this.
Okay, and now in here we can simply call our function
so it's going to be called back here.
But remember, that is just a keepScore function
and now we pass in true.
Because we know that here, when the answer is equal
to the correct answer, the answer will be correct.
And remember that this function here
which is effectively stored in the keepScore variable here
accepts a correct parameter.
So if it's correct, it's going to update the score
and return it, and if it's not correct, if it's incorrect,
it's going to only return the score
and not make any updates.
So in here we always have to pass true or false.
And since this returned something,
we need to store the score somewhere.
So let's say sc again, which is short for score,
and then declare it up here.
So var score, and that's because I'm going to call
the function here as well.
So score call back and this time with false.
And therefor the score is not going to be updated.
All this does is to return the current score.
And that's because we want to display the score
in the console either if the answer was correct
or if it was false.
So we always need to retrieve the score value
from the function, which again has access to it
because of the closure.
Let's now write a method for that.
So a method which is going to display
the score in the console.
So question.prototype.displayScore.
Okay, and actually we need a parameter here
which is the score.
So all we do in here is to simply console.log the score
so "your current score is" and then the score.
And then simply like a separator line,
so that we have our questions nicely separated.
So something like this.
And now all we have to do is to call it here.
So this.displayQuestion and then pass the score into it.
And once again, we have access to this method here
because of the prototype chain.
Because this variable here will point to the object
on which this method here was called.
So let's check answer method was called
and then of course it has access
to the displayScore method as well and so it's called
and then prints our current score to the console.
So does all of that make sense to you?
Let's now check it out if it works.
So we know all of the answers by now, right?
Well something's not really working here
because it printed two questions here now.
So let's now check out what's going on here.
So I'm going to exit the game
so that we can check out what's going on here.
Everything looks good here, actually.
Well, what I see here, oh, so here we return a score
and not sc, so we were currently returning
this function here instead of returning sc.
So this was something really wrong,
so maybe that was the reason
why this wasn't breaking properly.
So let's check it out again.
So coding is fun.
So you see that this is still not working fine
because we have still two questions here
so this kind of means that the displayQuestion here
is called twice.
So this is really wrong, let's check it out again.
I see that here is probably the problem.
So here we have displayQuestion,
which is this method up here
which displays a random question
but instead of course it should be displaying the score.
So in here, we of course don't want to display
the question again, but the score.
And it's completely normal that these kind of bugs
happen in programming, so this is just a matter
of a small distraction and then you can cause
these kind of bugs.
And then all you have to do is think about
why is this happening and try to hunt these bugs down.
Basically to find where you did a mistake.
And I'm pretty sure that this one here was the mistake.
Also because the score was never appearing
and also this line here was never appearing.
So this means that we were not really
calling this method anywhere.
And so this is here the place where the bug has to be.
And now I'm pretty confident that it's going to work.
So fun, and now the current score is one, so great.
Then the same question, and it was updated to two
so it's working, so the closure and this mechanism
that we coded is working.
So one now, so a wrong one, and the score stays at two.
Now it's three, now let's put a wrong answer again
and yeah, the score stays at three
and so everything is working properly.
Exit and that's it.
So take a look at this code again
and try to really understand why this score function here
works the way it does.
We learned everything about this throughout the section,
but it can be a little difficult
when you actually see it in practice.
So make sure that you really understand
how and why all of this works.
Alright, I would say challenge completed.
So see you in the next lecture.