[MUSIC] In this lecture, we will discuss, displaying image position, as well as assigning image position from a geocoded address, and then we'll enable caching for $resource. Now, prior to this lecture, I checked in a few skeletal files for the UI, and some specs. And we're looking at the results of a portion of those specs right now. During this lecture we're going to focus on the following three tests, the ability to be able to display the location of an image, namely the position, the ability to put in an address for an image and have it geocoded. And then, the ability to save that geocoded information with the image for future displays. So, if we look at our image, based upon our previous view implementations, we have no information telling us its location. But if we inspect the network and refresh the page and display our image again, we will notice that it's coming back from the service with a position. We just need to display that at the moment. All right, so in order to do so, I'll come into the image editor, come down the page a little, and put in a block of HTML. We're already receiving the image and it's available to us in the view model under the item element. And so, since this is the only thing the image carries with it, we'll display what we have. So, if I refresh to the display, we notice now we are showing the longitude and the latitude. And if we look at our results, that's all we were really looking for, display the asisgned position. Now, what we would like is the user to be able to put in a portion of an address, have that geocoded, and have the formatted address and the position available to be used in the image component. So, what we want to be able to do is to log in as the organizer and to be able to change this lat and long by plugging in an address. This next change is not going to be that easy, but it's not going to be that hard either. Let's start with the view first, and let me put in a block of code. So, what we want to do is to be able to put in an input area that the user can assign an address. Let me constrain this just a little bit more. So, if the user can update the image, then we're going to display a label of use this address, that I'm getting ready to type. And then we'll have an input area for the user to type in, which will be assigned to the address variable in the view model. And the input field will only be shown if they can update. And then when they click away from the field, we're going to call a method on the controller to say, can you geocode whatever's in that input field. And then, when it is geocoded, let's display the format address that comes back And let's continue to update this area as the user changes locations, okay? And so, what we need now is a location by address method off of our controller. And we'll go into the images component in order to add that method. Now, before we start editing our component, I want to point out a few things. If you look in this upper left, I have all ready added a module. I've all ready added a service, the skeleton of a service, that's going to do our geolocation and have added those to the JavaScript manifest. I've all ready injected the skeletal geocoder service into our ImageEditorController and it's ready to be called, not necessary function at this time. So, of course, in order to enable our webpage to call our controller back to locate by address, we need to add that method. Well, let's register it right now. So, we'll go ahead and add a location by address, just print out a little bit of debug at first. And what we're fundamentally going to want to do is to call the geocoder getLocationByAddress, but we don't know all the details yet of how that works. So, let's us go over in finish implementing that. So, I've got the shell of geocoder service that's going to call our back-end locateByAdress, locateByPosition based upon inputs the caller is providing. So, one of the fundamental things we need are the services that we're going to call, the resources, and they are off of the APP_CONFIG.server_url and go to the API/geocode/addresses. That's what we just finished implementing in the previous lesson. Now, as far as get it by address, we just need to call the address as resource, with a get, and to pass in a query argument of address with a string provided to us by our caller. And, of course, we owe our caller a result and that'll be a proxy object and it'll eventually get filled in with the data. But until it's filled in, there will be a dollar promise available off of what's getting returned. And then, for the get by position, we just need to call the positions resource with a get and we want to pass in a longitude and latitude, which is pretty much what we're asking to be passed in but all we really care is that there's a longitude and latitude property, whatever implements the position. And as with by address we want to return a result. And again, the result is a proxy that will eventually, the data will get filled in as the response is returned. But until it gets filled in, there will be a dollar promise that we can listen to. Okay, that looks pretty much it for the geocoder service. Wasn't much to it. It was kind of easy. So, if we go back to our location by address, all right, the details that we're missing is that we could just assign it to location and then when it does get completed, that location value will be filled in. However, we want to do a little bit more. We want to do some behavior when it gets resolved. So, let's look at the dollar promise. And implement a call back. And let's have this call back go ahead and assign the result to the location. But also, what we want to do is extract the position out of the location and assign that to the image. This is what has the lat and the long. And then, since it's early, let's go ahead and print some debug. Okay, with that we should be able to get some activity. If I refresh my display, come back in to my images, if I come in and say 901 Pratt Street, Pratt in Baltimore, and then click away, you notice that it went out and did a geocode to our service API. Found out that the formatted address was really West Pratt Street and it was in Maryland with a zip code in the United States, and then this being the geocoded address of that position. Now, to make things look a little bit more obvious, let's, I don't know, let's go ahead and put it in South America and now the latitude should go in the negative direction, okay? So, we've gone down to negative latitude and we put it some place else, okay? So, that's giving us a value at this point and time. Okay, so I'm not saying it's the best user interface in the world, but we're able to do is take a user from a typed in partial address, go ahead and fully resolve that into a longitude and a latitude. So, when they supply an image, they don't have to know everything. I mean, obviously, we don't want them to have to know the longitude and the latitude values. Although sometimes, that's not so bad either. Better user interfaces can be created, that's for sure. Just some functionality here. All right, if we look back at our tests, we're actually passing all three tests now, because once we put the position within the item that got returned, then it was there to be assigned the next time around. And to make some of this a little bit more obvious, I don't have a test for this, but I'm just going to go ahead and informally put it in anyway. Then at during reload. Assuming that we're able to get the G location for the image, we should be able to also do a G location by position and be able to fill in that street address. So, now when we do a refresh, you notice that the street address comes up immediately. And if I were to say South America. Click away, and then go ahead and update the image, clear and then come back, you'd notice that it's in South America. And we don't have to necessarily interpret this longitude and latitude. And then, if we log out, let me see, okay, there it is. Log back in as Alice. For a more complete address, update the image. Log out, hey, where's the railroad? Okay, there's where it is, okay? One would argue that this is probably information that we ought to send over with the image or the thing image, but it's available to be had, okay? We're looking pretty good on being able to do geolocation based on the image. And we now have a geocoder service that we can hand information and say, give us an answer back so we can put onto our view model and pages. All right, one thing the tests really don't show is all the work that we did in caching. What I want to do is demonstrate something right now that isn't going to quite work the way we want. So, let me go to the museum. You notice it went off and looked up positions by latitude and longitude, and came back with an address. If I were to clear the image and come back in, you notice it is asking for that position again. There's no caching going on. The same is true as if we look up addresses, we keep looking things up multiple times. And if we look in the headers, we see that we're getting an ETag back but the request headers are not sending anything out. And the answer to this problem is, is NG Resources implemented in terms of $HTP, and neither cache by default. So, we have to tell it. So, if we come back to our resource, and in the third parameter, and for the get, we define cache as true. I'm sure there is more elaborate configurations than that, but let's implement the default caching, which is all we intend to use. So, if I refresh the browser, and let me log in as somebody other than Alice. I've been picking on her images for a while, and they're all kind of getting into the cache. So, let me come in as Carol, and she's able to edit the blue blubber jellies. And you notice, a position comes up the first time we come in. And if we clear the image and come back in, that position has been cached. We're not looking that up again. And to boot, if we come in and do an address lookup, assuming I haven't looked this one up before, it'll do a lookup. But if we click in and out, we're not going to get the lookup performed. If we mung it a little bit, take away the USA to make it look a little different, you'll see that the call got made. But as we get that, and we come back with USA again. If I type that right, that's not going to occur, if I get rid of the A in the US, we get a look up, okay? So, it's good to see all that work on the caching on the API layer put to use on the UI. And since the cache control says that we can hold onto this for about a day, it's going to be a while till we go back and hold them again for that value, okay? In summary, we added image position. And we displayed a formatted address, after reverse geocoding the original position and geocoding a newly entered address. And we saw how $resource doesn't cache by default, but we could enable that quiet easily to have it honor our ETag caching protocol. What's next? Current origin, identify origin by address. Let's start establishing an overall origin context for our UI so that components can rally around. And let's identify the first position to be our origin using an address look-up.