Angular.js

Angular.js $location Example

One of the scenarios that you may have encountered while using AngularJS in your project is having to use the current URL of the website. It becomes especially important when you have to do routing or when the current URL is crucial to the well-functioning of your web-app. There’s an AngularJS service we use whenever we have to deal with these cases: $location. Below, you can read about how you can use it too!

1. What is $location?

$location is an Angular service which enables you to have the URL in the browser’s address bar parsed and made available for use in your application. From there you can go on to use it however you wish, be it changing it, or using it to refresh your page (this you’d have to do manually). The changes that are made on the URL directly from the address bar will be immediately reflected into your $location, and similarly the changes you’d perform on the $location will be made visible into the address bar of the browser you’re using.

1.1 $location functions

The $location service has a number of functions which serve to define this service as much as make itself useful in many ways related to URLs. One of these functions, as mentioned briefly before, is the ability to expose the current URL found on the address bar, so that you can either watch or change it, depending on what your application requires.

The second function is providing you with a “live communication channel” with the address bar. That consists of a synchronization between $location and the address bar that reflects all the changes in a two-directional manner whenever you change the URL directly from the address bar, click on a forward or backwards button in the browser, click on a history link or another random one in the page you’re currently viewing.

Another very important function of the service is enabling us to view the URL we’re getting not only as a simple object but as a set of methods. You have a URL in your hands? That translates to having a full set of methods such as protocol, host, port, path, search and hash. That would make it much more easier for you to understand and modify the URL you’re getting. Handy, right?

1.2 $location vs. window.location

If you already know what window.location does, and are just now being presented to $location you might be asking yourself: are they the same thing? Well no, however their purpose is the same: to allow reading or writing the browser’s current location. What are some other similarities and differences between them?

Regarding the similarities, I’d say that is about it: they have the same purpose (and to be fair $location is based on window.location on that one) but are different in how they approach bringing that purpose to fruition.

That would mean we would have an impressive number of differences between the two. The first one of the bunch would be the API approach. While window.location would return a straightforward object with all it’s properties and methods and whatnot (which can also be modified directly), $location would return getters and setters, similar to jQuery.

The next aspect to consider would be the integration. window.location cannot be integrated with neither the Angular application life-cycle, nor the HTML5 API. That would be pretty easy for $location, which can do both, and seamlessly at that.

The last difference would be in whether they have awareness of the context from which the document is loaded or not. Can you guess which has this and which not? If you guessed $location would win this round too, then you were completely right! While window.location.pathname would include the docroot in the result it’s give to us, it’s colleague from the other company would just return the actual path from which the document was loaded. Time to upgrade!

2. Configuration

The $location service works differently based on what configuration it’s currently using. Yes, you have to configure it before using it! For some applications the default configuration is more profitable, for others you have to change it in order to get new features made available to you. Once you have the configuration instantiated you can interact with the $location using the getter and setter methods that come with it, which we will get to discussing a bit later.

2.1 The $locationProvider

There are two configuration modes that you can use: the Hashbang mode and the HTML5 mode. Before explaining each of them we’ll first take a look at one crucial element that we’ll use to configure our $location. That would be the $locationProvider.

$locationProvider is a provider in the ng module that is used to configure how the application’s deep linking paths are stored. It has only two methods which are used to set the parameters as we want them: html5Mode() and hashPrefix().

The first one, html5Mode(), is a boolean value or object that takes only one parameter which would define the mode we want to use on our $location. This parameter can be either TRUE in case you want to use the HTML5 mode, FALSE in case you want to use the Hashbang mode which is also the default one, or requireBase:true to see relative links.

The second method, hashPrefix(), is only used in Hashbang mode or in legacy browser for the HTML5 mode. It takes only one argument which would be the prefix that will be used for Hashbang URLs.

The syntax for the configuration is fairly simple and would look a lot like the code snippet below:

syntax.js

$locationProvider.html5Mode(true).hashPrefix('*');

What we’ve done here is just invoke the methods mentioned above by using the dot operator to link them with the $locationProvider. Still, you might be unclear, since we never clarified what each of the configuration modes meant, but we’ll clarify that on their own time.

2.2 Getters and Setters

We mentioned that after configuring the $location on the mode in which you want to work on, there is one way through which you can communicate and interact with it. That would be getter and setter methods. But what are these methods?

The getter methods are used for the read-only parts of the url. There are four getter methods:

  • absUrl() – returns a full URL representation with all segments encoded according to rules specified in RFC 3986.
  • protocol() – returns the protocol of the current URL.
  • host() – returns the host of the current URL.
  • port() – returns the port of the current URL

With that we get on the the methods that are both getters and setters. Those would be:

  • url() – it has only one optional parameter. When this parameter is omitted, the method returns the URL, and you can use it to change the path, search and URL when you give it an argument (which would be a URL in itself). Understandably, the method would return $location.
  • path() – is a method that would give us the path of the current URL when invoked without any argument, and change that path if it does take one as a parameter. Note that if you pass a path as a parameter, you have to start it with a forward slash [/], so that the method can add it in case it is missing.
  • search() – is another method doubling both as a getter and a setter. If it’s used without any arguments it will return the search part of the URL as an object. However, if you want to use this method to set the search part of the URL, you would have to pass it two parameters: the first one would be the part you want replaced, and the second one would be what you want it replaced with.
  • hash() – is a method that gives us the hash part of the URL when called without an argument, and changes that fragment when called with a parameter.
  • state() – will return the history state object when called without any parameters and change that object when called with a parameter. Note that this method is valid only on HTML5 mode.

That’s about it.

3. Configuration Modes

We mentioned before that there are two modes of configuration for the $location service: the Hashbang mode and the HTML5 mode. Applications use the same API in both modes, which means you can use whichever mode you want, according to your own needs and wants related to changes of the URL and browser history management.

The best way to illustrate the difference between these two modes is by taking a URL and analyzing it in detail. Let us suppose we have the URL below:

  • http://website.com:9090/#!/mypath?param1=value1#hashvalue

Let’s start taking it apart piece by piece. You will see http first, which is the protocol that the URL uses. You see it in almost all the URLs you visit on the internet, as it’s one of the most used ones. It’s name is an acronym that stands for “HyperText Transfer Protocol”.

Next up is website.com which would be the domain of your website. It’s followed closely by the port number which in our case is 9090 but could be another number such as 8080 or 3306.

Now you’ll see the element that differentiates a URL using Hashbang mode from one using HTML5 mode. It’s #! in our example, but could be #* or something else based on the hashPrefix that you have used in the configuration.

Next, there are three elements which we can get for each URL by using the getters and setters: the path, the search and the hash part, respectively /mypath, param1=value1 and hashvalue.

The same URL but using HTML5 mode would look like this:

  • http://website.com:9090/mypath?param1=value1#hashvalue

But let’s delve more into each mode and see how can we configure and interact with each one.

4. Hashbang Mode

The Hashbang mode can be applied either by configuring your app to use that one specifically or even just not configuring it at all, since it’s the default configuration of the $location service. That wold mean that all the browsers are obliged to use the Hashbang URLs.

This mode does not require server-side configuration, and it also does not allow the links to be intercepted and rewritten, as they work as expected. The configuration for this mode could be like below:

config.js

function($locationProvider) {
    $locationProvider.html5Mode(false);
    $locationProvider.hashPrefix('!');
  }

As stated previously, that would be done by giving the necessary parameters to the methods html5Mode() and hashPrefix() of the $locationProvider. Below you’ll see an example of how easily you can communicate with the address bar regarding the URL:

example.js

function($location) {
    $location.absUrl() == 'http://website.com:9090/#!/mypath'
    $location.path() == '/mypath'
    $location.protocol() == 'http'

    $location.path('/foo')
    $location.absUrl() == 'http://website.com:9090/#!/foo'

    $location.search() == {}
    $location.search({a: 'b', c: true});
    $location.absUrl() == 'http://website.com:9090/#!/foo?a=b&c'

    $location.path('/new').search('x=y');
    $location.absUrl() == 'http://website.com:9090/#!/new?x=y'
  }

We used the same URL as the one in the illustration, so that you are as clear as possible on this. First of all, we used the getters path() and protocol(). You can already predict their result. Then you can see how does the usage of the setters affect the URL. Easy, right? Let’s see how is this different than the HTML5 mode.

5. HTML5 Mode

The HTML5 mode is based on the HTML5 API so that means all the getters and setters will interact with the URL through the HTML5 history API which would mean that the URL would use regular path and search segments, to counter it’s Hashbang counterparts.

To use this mode you will have to configure it, and beware that while it will work correctly on new browsers, old browsers will fallback on the Hashbang mode. As you can see for yourself, the $location service uses the best mode available, and you would not have to worry if the browser supports the HTML5 history API or not and just code on.

Differently from the Hashbang mode, this one allows interception and rewriting and also requires some server-side configuration. While in Hashbang mode the page would be reloaded automatically after each modification except for the hash fragment, that never happens with HTML5 mode.

Let’s see how the configuration code snippet would look like:

config.js

function($locationProvider) {
    $locationProvider.html5Mode(true);
    $locationProvider.hashPrefix('!');
  }

It’s pretty simple, the only thing that changes from the previous configuration is the argument passed to the html5Mode() method of the $locationProvider. However, the thing that might confuse you would be the usage of hashPrefix() since we’ve already established that it’s only needed for Hashbang mode. The reason we do specify it is because our user will need it in case it’s browser doesn’t have the support for the HTML5 history API.

Let’s see how the example we used in the section above would change now that we are using a different configuration mode:

example.js

function($location) {
    $location.absUrl() == 'http://website.com:9090/mypath'
    $location.path() == '/mypath'

    $location.path('/foo');
    $location.absUrl() == 'http://website.com:9090/foo'

    $location.search() == {}
    $location.search({a: 'b', c: true});
    $location.absUrl() == 'http://website.com:9090/foo?a=b&c'

    $location.path('/new').search('x=y');
    $location.url() == 'new?x=y'
    $location.absUrl() == 'http://website.com:9090/new?x=y'
  }

As you see, the differences are close to none. In fact, you might not even notice it at all, it’s that small. To do that, you have to focus on the URL we’re using all along. It doesn’t contain the element #! that would mark it as a Hashbang URL.

With that, you’re done and ready to use $location to your liking.

6. Download the source code

This was an example of $location in AngularJS.

Download
You can download the full source code of this example here: $location

Era Balliu

Era is a Telecommunications Engineering student, with a great passion for new technologies. Up until now she has been coding with HTML/CSS, Bootstrap and other front-end coding languages and frameworks, and her recent love is Angular JS.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button