The last piece to the puzzle to really get all this working is to add an event listener for the newLocationMessage event. In index.js we can call socket.on to do just that. We're going to pass in our two arguments. First up is the event name we want to listen for, newLocationMessage, and the second and final argument is our function. This is going to get called with the message information once the event occurs:
socket.on('newLocationMessage', function (message) {
});
Now that we have this, we can go ahead and start generating the DOM elements that we want to spit out to the user, and just like we did above, we're going to make a list item and we're going to add our anchor tag, our link inside of it.
We're going to make a variable called list item and we're going to make a new element using jQuery. As that first argument we're going to pass in our string and we are going to go ahead and set it equal to the list item:
socket.on('newLocationMessage', function (message) {
var li = jQuery('<li></li>');
});
Next up we can go ahead and create the second element we're going to need. I'm going to make a variable, call this variable a for the anchor tag, and set it equal to the return value once again to a call to jQuery. This time around we're going to create the anchor tag. Now the anchor tag uses the a tag, and the contents inside of the tag, that's the link text; in our case, we're going to go with My current location:
socket.on('newLocationMessage', function (message) {
var li = jQuery('<li></li>');
var a = jQuery('<a>My current location</a>');
});
Now we are going to be specifying one attribute on the anchor tag. This is going to be a non-dynamic attribute, meaning it's not going to come from the message object, this one is going to be called target, and we're going to set target equal to " _blank":
var a = jQuery('<a target="_blank">My current location</a>');
When you set target equal to _blank, it tells the browser to open up the URL in a new tab as opposed to redirecting the current tab. If we redirected the current tab, I'd get kicked out of the chatroom. If I clicked one of the links with the target set to blank, we'll simply open up a new tab to view the Google Maps information:
socket.on('newLocationMessage', function (message) {
var li = jQuery('<li></li>');
var a = jQuery('<a target="_blank">My current location</a>');
});
Next up, we're going to go ahead and set some properties on these attributes. We're going to set the text using li.text. This is going to let us set the person's name as well as that colon. Right inside template strings, we are going to inject the value message.from. After that value, we're going to add a colon and a space:
var a = jQuery('<a target="_blank">My current location</a>');
li.text(`${message.from}: `);
Next up, we're going to go ahead and update our anchor tag, a.attr. You can set and fetch attributes on your jQuery-selected elements using this method. If you provide one argument, like target, it fetches the value, in which case it would return the string _blank. If you specify two arguments, it actually sets the value. Here, we can set the href value equal to our URL, which we have under message.url:
li.text(`${message.from}: `);
a.attr('href', message.url)
Now you'll notice for all these dynamic values, I'm not simply adding them in template strings. Instead, I'm using these safe methods like li.text and a.attribute. This prevents any malicious behavior; if someone tries to inject HTML, they shouldn't be injecting using this code.
With this in place we can now go ahead and append the anchor tag to the end of the list item, which is going to add it after the text we just set using li.append, and we're going to append the anchor tag. And now we can go ahead and add all of this to the DOM using the exact same statement in case of newMessage event listener. I'm going to copy and paste it in the newLocagtionMesaage event listener:
socket.on('newLocationMessage', function (message) {
var li = jQuery('<li></li>');
var a = jQuery('<a target="_blank">My current location'</a>);
li.text(`${message.from}: `);
a.attr('href', message.url);
li.append(a);
jQuery('#messages').append(li);
});
With this in place we are done. Now I'm going to save index.js and restart things over in the browser. We made quite a few changes so it's alright if you had a few typos; as long as you're able to track them down it's no big deal.
I'm going to refresh both of my tabs over inside Chrome; this is going to get the new connections up and running using the latest client-side code, and to kick things off I'm going to send a simple message from the second tab to the first tab. It's showing up here in the second tab, and if I go over to the first tab we see User: test. Now I can click on Send Location, this is going to take about one to three seconds to actually get the location. Then it's going to go through the Socket.io chain and what do we get? We get the link My current location showing up for user one:

And for user two as well. Now if I click on that link, it should open up a brand new tab with the proper URL, latitude, and longitude information rendered in it.
Right here, we have the location for the user who clicked that Send Location button. With this in place, we have a fantastic geolocation feature. All you do is you click on the button; it fetches your current location no matter where you are, and it renders a clickable link so anyone else can view it inside Google Maps. Now before we go, I would like you to add a single test case for that brand new generateLocationMessage function.