‫As promised, we will now use
‫event emitters and listeners in practice,
‫and we start by creating a new file here.
‫So events.js and close up this one.
‫So to use the built in node events,
‫we need to require the events module,
‫and from that we're going
‫to require an EventEmitter class.
‫So, EventEmitter, this is kind of the standard name
‫for the result of requiring this events module.
‫So again this is a built in node module, okay?
‫And now to create a new emitter,
‫we simply create an instance basically
‫of the class that we just imported.
‫So very simple myEmitter
‫is a new EventEmitter.
‫So EventEmitter just like this.
‫So remember from the last video
‫that EventEmitters can emit named events,
‫and we can then subscribe to these events,
‫so basically listen to them,
‫and then react accordingly, okay?
‫So it's a bit like setting up
‫an EventListener on a dumb element,
‫for example, for clicking on a button,
‫and I'm sure you've done it before,
‫when working with JavaScript on the client side, right?
‫So our emitter will eventually
‫emit a named event, okay?
‫So let's set that up,
‫and let's simply pretend that we're
‫building an online store or something, okay?
‫So we can say myEmitter.emit(),
‫and then we can make up any event name that we want, okay?
‫So we want to emit an event called newSale, okay?
‫And using the example of clicking
‫on a button that I used before,
‫this emitting here is as if we were clicking on the button,
‫and so now we have to set up these listeners, okay?
‫And let me actually do that before here,
‫and so again we use our myEmitter object.
‫Enter that we use the on method, okay?
‫So on newSale and then the callback function ,
‫which is gonna get executed as soon as the event is emitted.
‫So as usually, let's simply to the console.
‫"There was a new sale!"
‫Okay, and let's add another one.
‫So remember that I said earlier
‫that one of the nice things about these event emitters
‫is that we can actually set up
‫multiple listeners for the same event.
‫So let's do that here,
‫and so again, of course, we're listening
‫for the newSale event,
‫(typing)
‫and then log just something else.
‫Doesn't really matter here.
‫So '"Customer name:', for example 'Jonas"'.
‫So, let's test this out,
‫clear the one from before,
‫and we use node,
‫and then events.js.
‫So, There was a sale and Customer name: Jonas,
‫and so you see already that it's working.
‫So, great, so this is the observer pattern, remember?
‫Where this one here is the object that emits the events,
‫and then these two here,
‫so this on and this on,
‫these are the observers.
‫They observe the emitter
‫and wait until it emits the newSale event.
‫And, of course, our emitter could also emit other events.
‫Like new customer or new order or something like that,
‫and we could then add listeners for that one as well, okay?
‫Now another thing that I wanted to show you
‫is that we can even pass arguments to the EventListener
‫by passing them as an additional
‫argument in the emitter, here.
‫So let's say that pass nine,
‫so in this case just a number,
‫and we then have a listener that wants to use that.
‫(typing)
‫So myEmitter,
‫(typing)
‫newSale,
‫and so now this callback function can take an argument,
‫and so let's call it stock.
‫So basically the amount of items that are left
‫from the product that we're selling here.
‫Let's use a template string.
‫There are now
‫stock items
‫left in stock.
‫So, if we run this now,
‫we should see There are now nine items left in stock
‫because we emitted this event
‫basically with a nine,
‫and the listener can then pick up this value here
‫as an argument of their callback functions.
‫So this stock variable here in this case.
‫So if you run this again,
‫then here There are nine items left in stock.
‫So, perfect, and you see that
‫these three logs here appear in the exact same order
‫that they are declared in the code, okay?
‫And so that's the normal behavior.
‫If we have multiple listeners for the same event,
‫then they will run synchronously.
‫So one after the other in the order
‫that they were in the code.
‫So this small example works perfectly already,
‫but if you were to use this pattern in real life,
‫then it's a best practice to create a new class
‫that will actually inherit from the node EventEmitter.
‫So, something like this.
‫(typing)
‫So let's say class Sales extends EventEmitter,
‫and that is ES6 or ES2015 syntax for class inheritance.
‫And again, I hope that you're familiar
‫with ES6 at the time you're taking this course, okay?
‫So in rote terms, the EventEmitter is a class,
‫so the one that we imported from events
‫into our sales class,
‫is the new class that we're creating,
‫and that inherits everything
‫from the EventEmitter class, okay?
‫Then in ES6 each class gets a constructor
‫which is a function that is run
‫as soon as we create a new object from a class, okay?
‫And what we need to do here is to call super,
‫and that's something that we always have to do
‫when we extend another superclass, okay?
‫So this is the parent class,
‫and this is the superclass,
‫and by running super,
‫we then get access to all the methods of the parent class.
‫So, again, EventEmitter in this case, okay?
‫And so now what we have to do is to
‫actually move this one down,
‫(clicking)
‫and so now my emitter is a new Sales, okay?
‫And so now it will work exactly the same,
‫and indeed, here we go,
‫and actually this mechanism that I just showed you here.
‫So basically extending the EventEmitter class
‫is exactly how the different node modules,
‫like HTTP, file system, and many other node core modules
‫implements events internally, okay?
‫So all of them actually inherit
‫from the EventEmitter class.
‫Okay, and with this small example working,
‫let's actually now try another thing.
‫So, since I was just now talking about the HTTP module,
‫let me actually demonstrate to you that
‫it is completely based on events, okay?
‫So we have this part working.
‫Let's create a couple of comments here, something,
‫and then create another example down here, all right?
‫And what we're gonna do is to basically
‫create a small web server,
‫and then actually listen to the event that it emits, okay?
‫So, up here we need to import the HTTP module,
‫(typing)
‫And then down here we can use it.
‫So we're creating a server,
‫and now I'm gonna do it a little bit different
‫than we did it in the first intersection okay?
‫But it actually works the exact same way.
‫So all I'm gonna do here is now http.createserver
‫and just like this,
‫and now what I'm gonna do is
‫to basically listen to different events
‫that the server will emit.
‫So for that, again, I'm using on,
‫and so if you see .on anywhere in a node project,
‫well, then you already know that you are listening,
‫or that the code is listening for an event, okay?
‫And so the one that we are listening here
‫is the request event, okay?
‫And so now it works just the same as before
‫we have a callback function
‫which gets access to the request and the response.
‫So nothing you at this point we did exactly that
‫in the node farm project, okay?
‫So, console.log
‫(typing)
‫"request received" and then let's also send something back.
‫(typing)
‫Just the same text actually, okay?
‫And, of course, we can listen multiple times
‫to the same event.
‫(clicking)
‫So let's just say here "Another request"
‫using some emoji here just to make it pop a little bit more,
‫and it's not appearing.
‫What's going on here?
‫Ah, here we go.
‫So, listening to a request,
‫and we can also listen to the close event.
‫So, server on close,
‫and that is the event that is fired
‫when the server, as you can imagine, closes down.
‫(typing)
‫Okay, so that is listening to the events,
‫and now, remember, we also have
‫to actually start the server.
‫So, and we start the server up
‫by using server.listen,
‫pass in the port, the address which is
‫localhost again for us in this case,
‫point one, and then, our callback function
‫which is optional but let's include it here again.
‫(typing)
‫"Waiting for requests..."
‫So, let's actually start this,
‫and we see Waiting for request...,
‫and the application is not shutting down,
‫and now you know why it doesn't shut down, right?
‫It is so because the event loop is
‫still waiting for incoming I/O, right?
‫So that's what we learned in the event loop lectures, okay?
‫Now let's actually do a request on port 8,000 on this URL.
‫(clicking)
‫(typing)
‫And here we go.
‫So, we see Request received.
‫So this works because as soon as there is a new request,
‫the server automatically emits the request object, okay?
‫And we can see that here of course,
‫and here in the console,
‫we see our Request received string.
‫I actually wanted to get another one here.
‫So, we can, of course, only send one response.
‫So here I should have another console.log instead.
‫So let, exit this, start it up again,
‫reload,
‫and, yeah, so now we get Request received,
‫which is from this first EventListener,
‫and another request from this second EventListener.
‫One thing that you're probably noticing
‫is that each of these here actually is logged twice.
‫So that means that the server is actually
‫emitting the request event twice as well.
‫So let's see why that is.
‫(typing)
‫So console.log, request.url.
‫So with that, we can now get access
‫to the URL of the request.
‫(clicking)
‫Let's quit it here.
‫Run it again,
‫reload,
‫and so we have one for the root URL,
‫and then one for the favicon.ico
‫So browsers automatically try to request
‫a favicon for each website, okay?
‫So that is why each of these appeared twice actually, okay?
‫So, you see that not always we have
‫to actually also emit events.
‫That is more when we try to use the EventEmitter on our own.
‫So basically, when we're trying to use
‫our custom events in our applications.
‫In this case, of course,
‫we have to emit the events ourself,
‫but if we're using a built in node module,
‫then these functions in there will many times
‫emit their own events,
‫and all we have to do is to listen to them.
‫So that's exactly what we did here,
‫and with that, I think,
‫you now know all you need to know about events,
‫and are ready to come with me to the next video.