- [Instructor] As I said before,
a basket is always for a given user,
and if you remember in user management,
we created this impersonate route before.
So if I click on the email address of a user,
we see that it somehow switches to user.
Let's look again what we're doing here.
So in Visual Studio Code now,
in our user route when I scroll down,
in the end I have this impersonate route
and you see that we write the user ID
into the session in line 92.
If I look at the index route of our shop,
so in routes, shop, index.js,
we see that we there look for res.locals.currentUsers,
so we look for the user object that is not just the ID
but the whole user and it's stored in res.locals.
Locals is a property on the response object
which is available to all templates
and if we look into our layout templates
that can be found in server fuse,
and you also see that I'm using
the pack template engine here.
When I scroll down, I see that,
I check for the current user in line 39,
this is available via res.locals
and if there is a user,
I print out logged in as current user email,
and also you see that I'm looking here
for a variable, basketCount,
and if it's there,
I also print out how many items are in the basket.
You might've guessed you're missing something here.
So we have to make the current user
and the basketCount available to the whole application.
To achieve that, I now go into my app.js file
and now on top, what do I need?
I need to user service to fetch a user
and also the basket service
to read the basket for a given user.
So I start by adding const UserService equals require
./services and I bring in the user service
and also want to bring in past basket service,
const BasketService
equals require,
./services/BasketService.
Let's add an empty line here,
otherwise this link will complain.
Now let's crawl down and
right here at line 39,
you see that I define a middleware here
that I'm already using for the
user notifications on the page
and this middleware will run with each request.
So we can now go ahead and after line 47 add,
so we want to check if
there is request.session.userID.
So we try to impersonate the user obviously,
and if so, I add a try-catch block.
If there is an error,
I will return next error
and in the try block I now add res.locals.currentUsers.
So we want to populate the current user with,
and now I add await UserService
and there, I now call getOne.
So I want to get this one user
and I simply pass in request.session.userID.
So now if the session contains a user ID,
the template variable for current user will be filled.
Next let's deal with the basket.
So I add now const basket
and I want to create a new instance
of the basket service for this user,
so I add new BasketService
and first I have to pass in config
and config is available in app.js,
then redis.client,
and the second argument, you might've guessed it,
I add request to session.userID,
and now I want to also get the
number of items in the basket.
For that, I first define an empty counter,
let basketCount equal zero.
Then let's use the basket service
to fetch all items in the basket.
For that, I add const basketContent
equals await basket.getAll,
and if there is something in the basket,
so I add if basketContents,
then I will now iterate over these contents,
with Object.keys, basketContent,
and for each element in the basket,
I get the item ID
and I can now in there increment the counter
by adding basketCount plus equals,
and here I have to add parseInt
because this will be a string
and I have to convert this to integer,
and there I add basketContents.
Add the index of the itemID
and I have to add the radix here,
so that's the base of the numeric system for the parseInt,
and once I'm done with that,
after the if statements,
I add res.locals.basketCount
equals basketCount.
All right, now let's see if this actually works.
So I head back into the browser
and let's first impersonate this user Jane.
I click on that and you see that
I get now this message locked in as Jane.
Then I head to the shop
and now let's try to add something to the basket.
So I click on, add to basket
and you see that I have got one item in basket.
Let's add a few more.
Of course it also increments when I add the same item again.
So this already looks great.
Let's see what happens when I now click on
this basket information here on my top navigation
and you see that I end up on the basket page,
and it says nothing here,
which is clearly wrong
because we just added something to the basket
and you might've guessed
that we have to also finalize this basket page here.
So I head back into Visual Studio Code,
and there I open routes, basket, index.js,
and in there I again remove now the comments
and the return statement from this get route here on top
and you see I'm missing the basket service
and the item service.
So I now add this const ItemService
equals require two levels up,
services/ItemService
and also the basket service,
const BasketService
equals require two levels up,
services/BasketService
and we also have to bring
config as an argument to our module exports
and with that, everything should be provided already.
So I hit save,
and let's head back into the browser,
and there I click on the basket link again.
Now you see that we have the list of items in the basket.
We also have this remove route
that we have to still implement,
so let's head back into Visual Studio Code,
and there, now that's really easy.
Let's just remove the return statement again,
and also the comment here at the end
and also the next statement.
Let's hit on save,
and let's see what happens
when I now click on remove from basket
and it's gone from the basket.
So that works now as well.
Now in the end, let's real quick
also look into RedisInsight
that they have opened here already.
Let's reload the page and you see that we have,
now first the session we talked about this before,
and now also we have a basket for this given user,
and this basket here has the hash key of the user ID on top,
and you see then the fields for the item ID
and the number of items in the basket as value.
Now, back on our shopping page, let's hit Buy Now,
and we see that this is not implemented yet,
this is because for placing and storing an order,
we will use MySQL,
and we will cover that in the next chapter.