‫Let's now finally finish up
‫this login functionality part.
‫And remember how I said that in this video
‫I wanted to implement a really nice alert
‫for when the user successfully logs in, and so
‫to see that let's log the user out
‫for now by removing the cookie manually.
‫Let's reload, and so now of course
‫the user should no longer be logged in,
‫and indeed it isn't.
‫As we already know, that's because the cookie
‫wasn't sent in the request.
‫So there is logged in middleware that we created
‫in the last video
‫did not put the user object into response.locals,
‫remember that?
‫So if it's not there the user manual will not be rendered,
‫and instead this part gets rendered
‫so that we now can click here on Log In.
‫So that alert that I was talking about before
‫I want it to show up here basically at the beginning
‫and then after a second and a half
‫we still want to do that reload.
‫So moving to the main homepage.
‫Anyway let's create some functions
‫for this alert in yet another separate file.
‫So new file,
‫alert.js.
‫All right, but now before we can actually move on
‫we need to think a little bit
‫about our front-end architecture here.
‫Now this course, of course, is not about the front-end,
‫but still we need to at least care
‫a little bit about it here,
‫because we're really starting to get
‫a nice amount of files here,
‫and including all of them into our pages
‫is not a good practice.
‫So
‫such as we've been doing here.
‫So this is not a good practice.
‫We should only have one big JavaScript file
‫which includes all the code.
‫So in modern JavaScript front-end development
‫we usually use something called a module bundler.
‫The most popular one is probably still Webpack,
‫but usually Webpack gives us a lot of problems
‫and it's really a pain to set it up.
‫So there's actually a very nice new kid on the block,
‫so to say, which is called Parcel.
‫So we'll take a look at that, see if it already shows up,
‫and indeed, that's the one.
‫So blazing fast, zero configuration web application bundler.
‫So that's exactly what we're looking for.
‫Simply a bundler which doesn't require
‫any complex configurations, because
‫we don't want to waste any time with that.
‫All right, so let's just go ahead and install it here.
‫So npm install
‫and I'm not sure if it's just Parcel actually.
‫So
‫let's go back here.
‫Probably that is Parcel.js or something,
‫because I remember the last time I installed it
‫it didn't work right away, so let's check that.
‫Yeah, indeed, it is Parcel-bundler.
‫Now we got some error.
‫Okay, so I forgot to save it as a dev dependency.
‫So we actually want it as a save dev, okay,
‫and that's because it's a development tool.
‫Now still something went wrong.
‫Let me try it with sudo here.
‫And so if it didn't work in your case as well
‫then just use sudo in order to get the proper permissions.
‫All right, so let's take a look at our package.json
‫and indeed here it is, all right.
‫Now if you're watching this video
‫some time after I recorded it
‫they might already have gone to version number two
‫and that as we already know
‫might introduce some breaking changes.
‫And so going forward from this point if you get any errors
‫that you didn't see here in the video
‫then please go ahead and install this package here
‫using version .1,
‫okay.
‫So basically
‫add one like this, okay.
‫So this then adverts you running into these weird errors
‫and hopefully it also saves me
‫from tons of negative comments
‫or negative reviews that expect me to update all my videos
‫every other week just because some tool gets updated,
‫and of course that's not possible.
‫So many times the easiest solution
‫is simply for you to use the same version
‫as I am using in the video, all right.
‫Anyway, now in order to actually use Parcel
‫let's add some scripts here.
‫So I'm adding one to watch or JavaScript.
‫Okay, and for that
‫I use the Parcel watch command.
‫This would actually already run just fine out of the box,
‫but I still want to configure a little bit,
‫because otherwise, it's gonna put me the final bundle
‫in some folders that I don't want them.
‫So let's specify which folder it actually should watch.
‫So that's public/JavaScript and then index.js,
‫so that's our entry point
‫and that's the file that we're gonna create in a second.
‫Okay.
‫Then the output directory
‫should also be into public.js,
‫okay.
‫Many times you will have different folders
‫for the development and for the output,
‫but in this case since it's a very simple architecture
‫I'm going to put the bundle file right in the same place
‫as the development files.
‫All right, let's also specify the
‫the output file
‫and so that should be bundle.js,
‫all right.
‫So now I can run this and it will then take a look
‫at this file here and see if something changes
‫or in one of the dependencies
‫and whenever that happens it will then
‫bundle all of the files together again
‫into this bundle.js file, all right.
‫Then let's also duplicate this,
‫because we also want a final,
‫let's say production version, okay.
‫So this one we are going to run ones where
‫they're really finished, okay.
‫So that takes a bit longer, but it also does
‫a bit more optimization stuff, but
‫that of course we don't need for development.
‫In development as always, we just want it to work.
‫So let's do npm run
‫watch:js, but before we do that let's actually create
‫the index.js.
‫Let's close some of these folders here.
‫It's a bit too confusing like this.
‫So index.js and let's just do a simple
‫console.log here for now.
‫Hello from Parcel,
‫all right.
‫Then let's also go to our base here
‫and then we'll actually now comment out all of these
‫and only include
‫the bundle file.
‫So again, one file which will basically contain
‫all the code that's in all the other files
‫and all their dependencies.
‫So let's give it a save, and now let's actually run this,
‫see what we get there.
‫And indeed, we got our new file, which is bundle.js
‫and it has all this bunch of code already in there,
‫okay, simply for this one line of code at this point.
‫But anyway let's reload our page here,
‫and hello from Parcel.
‫So that worked, and so now let's go ahead
‫and actually setup this file here.
‫So to avoid confusion let's close
‫these files that we no longer need
‫for what we're doing right now.
‫So that's a lot of stuff.
‫All right, this one either.
‫So now the idea is basically that this index.js file
‫is our entry file, and so in this one
‫we cannot get data from the user interface
‫and then we delegate actions to some functions
‫coming from these other modules here basically.
‫So we have now the login module,
‫we have our alerts module,
‫and so just like in Node.js
‫we can actually now export data from these modules.
‫So let's do that, and what I want to export
‫is this function here.
‫Now it works a little bit different
‫than it works with Node.js
‫because Node.js uses something called CommonJS
‫in order to implement modules.
‫I'm not sure if I mentioned that
‫when we first talked about modules,
‫but here in front-end JavaScript since ES2015 or ES6
‫there's something called modules in JavaScript as well.
‫The syntax is a bit different,
‫but actually the way it works behind the scenes,
‫but actually if you understand how it works with CommonJS
‫then this one here will be very similar.
‫So ES6 modules use the export import syntax.
‫So here all we need to do is to say export
‫and then whatever we want to export from this file,
‫and that's really it.
‫Now this piece of code here we will actually use it
‫in the index file.
‫So remember how I said that this file here
‫is more to really get data from the user interface
‫and then delegate the action.
‫So that's exactly what we are doing here, okay.
‫So then here we only have this kind of module
‫which then exports the login function.
‫Then we can import that in here
‫and call login right here in index.js
‫and that works like this.
‫So import instead of require
‫then the name of the variable that we want to import.
‫So I'm using curly braces here.
‫So it's called login
‫and then from the name of the file.
‫Which in this case, same directory, login.
‫Now let's also disable eslint here again,
‫and I used these curly braces here,
‫basically because we're doing the export in this way,
‫but there's also something similar to module.export
‫which is kind of the default export.
‫So in ES6 modules it's actually called a default export.
‫So in that case we then would not need these curly braces.
‫Okay.
‫Right now we need to do it like this,
‫because well that's the name of this function
‫that we exported, all right.
‫Now something really important as well in this login
‫is that we used axios.
‫And remember how I said that we were going to install it
‫actually from npm as an npm module, right?
‫So let's do that now, and actually because we already
‫commented out axios from here.
‫So right now login cannot use axios.
‫Well because we no longer included it here.
‫So let's go add, open up a new terminal
‫and install axios into our project.
‫Then now all we need to do is to say import axios
‫from axios, and that's it,
‫all right.
‫So this file, for now at least, is done
‫but let's not close it because we will
‫still need it very soon.
‫Next up we should actually also install a polyfill,
‫which will make some of the newer JavaScript features
‫work in older browsers as well.
‫So let's say npm install
‫and then this one here looks a bit weird.
‫So let's add babel/polyfill,
‫like this.
‫Then up here we will do
‫import
‫just like this, all right.
‫So this one here we do not save it into any variable,
‫because that's not necessary at all.
‫All we want this to do is to basically be included
‫into our final bundle to well polyfill
‫some of the features of JavaScript.
‫All right, and so that's also why it's here
‫in the first line of these imports.
‫Anyway, let's now import this mapbox as well.
‫For that we actually need to first create a function
‫which is going to do all of this stuff here.
‫Okay.
‫So let's create
‫export
‫displayMap, which will take in the array of locations.
‫So that will then actually be read in the index.js file,
‫all right.
‫So again, index.js is more for getting data
‫from the user interface, so from the website,
‫and then delegating some actions into these other modules,
‫all right.
‫So therefore, this stuff here will be done inside of index.
‫Let's do it up here.
‫Then import
‫displayMap
‫mapbox,
‫all right.
‫So let's call that as well
‫with the locations.
‫Now remember way back when we actually created this map
‫and remember how it asked us if we wanted to use
‫the mapbox library on npm?
‫So we could now go ahead and actually use that one
‫instead of this one that we're using right now.
‫So
‫well it's not here.
‫Yeah, so this one.
‫So this here is the mapbox library
‫that we're currently using, but again
‫there's also an npm version.
‫So then we would not need to have this one.
‫However, for some reason there's a problem with
‫using this library together with Parcel, okay.
‫So other people actually run into this issue.
‫So we cannot use the mapbox npm library
‫together with Parcel.
‫So that's a reason why I'm still doing it like this.
‫Okay.
‫So mapbox is completed with this.
‫This we don't need anymore, as well.
‫Now let's actually get rid of some of these errors
‫that we saw down here.
‫Well now they're no longer here,
‫but for example we had the problem that
‫this code here created some errors
‫when we were on pages that didn't have this map here, right.
‫Because of course on the detail page has this map
‫so this element, but then this code of course
‫runs on all the other pages,
‫that will then create errors there.
‫So let's fix that.
‫So what I'm doing here is first to create an element
‫with this and then test if it actually exists
‫before we execute this line of code.
‫So we will create some DOM elements here.
‫And here I'd say
‫delegation.
‫So if mapbox
‫and only then to these two actions here,
‫okay.
‫Here it's also then mapbox
‫and that's much nicer.
‫Here let's also put values,
‫and I'm going to put these two
‫because actually we might need them
‫or actually we will need them for other stuff as well.
‫So this way it's a bit cleaner.
‫Let's also only add this event listener here
‫if this element exists, right.
‫Because well, again, it will create an error if it doesn't.
‫So loginform,
‫and so
‫if
‫and then let's reuse it here, give it a save,
‫and so now that looks better.
‫Okay.
‫Let's actually close this terminal.
‫This you should of kept bundling our code together
‫each time there's a save.
‫Let's just save it here again.
‫Okay, so I hope that changed now.
‫So let's go ahead and try that out.
‫So if you can still login at this point
‫well then that means that it did actually work.
‫Well maybe not.
‫Let's try that again here.
‫All right, so there's something wrong going on here.
‫So as always let's log this email and password
‫to the console here.
‫I mean, because we already know that actually
‫this function here is called, right.
‫Otherwise, we wouldn't even get the error.
‫Right, because that error is clearly coming from our API.
‫So all of what we have here is actually working, I believe.
‫Let's take a look at the console.
‫So it appears that there are actually no
‫username and password.
‫Okay.
‫I'm not sure why that is.
‫Let's take a look if actually we do get something.
‫So login and I will also
‫log these right here,
‫not here
‫but here.
‫And so apparently the problem
‫must be that username and password
‫are not really defined.
‫Oh, and now of course I can see why that is.
‫What a stupid mistake.
‫So we're trying to read these values here,
‫right in the beginning when the page loads,
‫and of course at this point these values are not defined.
‫So we of course can only define them
‫right here in our event listener, right.
‫So by the time this function here is called
‫well then of course email and password are set
‫so then it's the time where we can read them.
‫So that was kind of stupid,
‫but, you know, sometimes that kind of stuff happens.
‫Now let's actually copy this here.
‫This time we are logged in successfully,
‫meaning that our code here still works.
‫Great, and so now let's do the final part
‫that we wanted to do in this lecture,
‫which is actually creating these alerts, all right.
‫So let's create a function called show alert and export it.
‫So then in login we will import this function
‫and use it there.
‫So showAlert
‫and this as an input will get a type and a message,
‫so just like this.
‫And this type
‫is either success
‫or error,
‫okay.
‫Because depending on this input we will then
‫have different CSS for each of these alerts
‫and you will see that in a second.
‫So what we're gonna do is to basically create some
‫HTML markup here and then insert that into our HTML,
‫so it's something really easy.
‫So a markup and the template string
‫and now some nice HTML.
‫So it's simply a div with a class of alert
‫and then
‫alert -- so a modifier
‫with our type.
‫Okay, and so that's why it needs to be either
‫success or error.
‫So let me quickly show that in CSS,
‫because I think it's really important to really know
‫how all of this plays together, okay.
‫So here we have our alert class
‫and then alert success and alert error.
‫All right.
‫As always let's disable eslint here,
‫okay, and get rid of this
‫and now of course here then goes the message
‫that we pass into this function.
‫Of course we could then go ahead and use this
‫all over the application, but in this case
‫we only need it actually here for our login.
‫So document.queryselector,
‫and so now here we select the element
‫where we want to include this HTML that we just created.
‫So that's actually right at the beginning
‫of the body element.
‫So right at the top of the page.
‫So body,
‫and then insert adjacent HTML, so this one here.
‫If you took my complete JavaScript course
‫then all of this here will be nothing new to you,
‫okay.
‫So here we can specify a couple of keywords,
‫and in this case we want afterbegin.
‫So basically what this means is
‫inside of the body, but right at the beginning, all right.
‫Then the HTML, so the markup,
‫that we actually want to include.
‫Great.
‫So this is going to create a very simple alert
‫based on type and method, but now we actually also
‫want a function for hiding alerts.
‫So let's create it here as well, export,
‫and probably we don't even need it outside of here,
‫but still for reusability it's always a good idea
‫to export all of this.
‫This one doesn't need to take in any argument.
‫So now all we're gonna do is to
‫select the element with the alert class
‫and then after that remove it.
‫So queryselector
‫alert.
‫So exactly the same class name as here.
‫Then we need to use a JavaScript trick
‫where we need to move one level up to the parent element
‫and then from there remove a child element.
‫So if there is an element then
‫element.parentElement.removeChild
‫and then the element.
‫Okay.
‫So again, that should just be basic JavaScript
‫or basic DOM manipulation.
‫So since this is a node course
‫I'm not going to go deep into that.
‫Anyway, what I want to do here now
‫is to whenever we show an alert
‫first hide all the alerts that already exist.
‫So we always just to make sure
‫always run hideAlert.
‫Then finally I also always want to hide all the alerts
‫after five seconds.
‫So window setTimeout
‫hideAlert
‫after five
‫seconds.
‫All right, and now let's import that here.
‫Display alert it was called, right?
‫Oh showAlert, with type and message.
‫So showAlert
‫from
‫right from that and so ...
‫Yeah, so we want to use that right in this place.
‫So instead of the JavaScript alert we want to do
‫showAlert, all right,
‫and here the same.
‫We still need to specify the type here,
‫and so that's success
‫in this case and here
‫it is error.
‫We hit auto-completion.
‫Okay, that's better.
‫So let's test it out.
‫And first of all we need to logout by deleting this cookie.
‫Reload,
‫login,
‫and now I'm testing it first with a wrong password
‫and here we go.
‫So incorrect email or password right in our nice alert
‫and you saw that after five seconds it disappeared.
‫Of course we could have put some
‫nice animation there and everything,
‫but I think like this it's already more than enough.
‫So let's see that again just quickly,
‫and so that's what it's going to look like,
‫but when it's correct then of course it should be green.
‫So yeah, logged in successfully
‫and we see a reload after one and a half seconds
‫and so now it really is working.
‫That's our complete authentication on the front-end.
‫That was a lot of work, but if you ask me totally worth it.
‫Now the only thing that's missing is
‫us actually logging out when we click this button here.
‫So right now that's not the case
‫and so in the next video let's fix that.