Pages

Sunday, November 30, 2014

AngularJS : Dynamically Set Page Title

You may also like to see:


With AngularJS you create Single Page Application (SPA) which means you have only one page of your application and dynamically you change the content of that page. So it means that there is only one time rendering of your main Html after that you can switch or append the views without re-rendering.

As you have one page for your complete application, but you need the different page title property for each of your page. For example : home, about us, contact us, services etc. So you need a mechanism so your page title automatically get updated when you route to any page.

Lets see how can we achieve this with angularJs.

First thing you need to make sure for the implementation is that your ng-app="AppName" directive should be on html tag as title tag is in head section and to make it in application scope so you can update it within angularJS application you need to make it accessible from application.

<html ng-app="app">
   <head>
     Website Name
...


Now title tag is expecting title property in scope and since we need this common property in all of the controllers also title tag to be in that controller scope but instead of adding this property to all controllers we move this to rootScope and as rootScope is accessible from all over the application (under the ng-app="" scope) that's why we added ng-app directive to html tag.

Here in this code I am using Ui.Router which I found best and easiest for nested views and routing implementations.

Here we set the title property to all the routing object so now each route know the page's title property they are redirecting to.

//here we need to inject ui.router as we using it for routing
var myDemoApp = angular.module('myDemoApp', ['ui.router']);

//$stateprovider is the service procided by ui.router
myDemoApp.config(['$stateProvider', function ($stateProvider) {

//create route object
    
    var home= {
        url: '/home',
        templateUrl: 'views/Home.html',
        controller: 'HomeCtrl',
        title: 'home'
    },
    aboutUs= {
        url: '/aboutus',
        templateUrl: 'views/AboutUs.html',
        controller: 'AboutUsCtrl',
        title: 'About Us'
    },
    contactUs= {
        url: '/contactus',
        templateUrl: 'views/ContactUs.html',
        controller: 'ContactUsCtrl',
        title: 'Contact Us'
    };

//Now add these route state privider

    $stateProvider
       .state('home', home)
       .state('aboutus', aboutUs)
       .state('contactUs', contactUs);
}]);


Now each rout has attached the title property with, we need to access this property and set it in $rootScope so our title tag can have access on it.

Now we going to set this property form route configuration object to $rootScope service within each controller and for this we need to have access on state object in controller. Here we will use $state service of ui.router that will make state object available in controller.


angular.module('myApp')
    .controller('myController', ['$rootScope', '$state', function ($rootScope, $state) {

        //set property to rootscope
        $rootScope.title = $state.current.title;

}]);

Similarly each controller will set this property to $state.current.title or custom text which will be render in title tag.

Another easy way to achieve this is to assign it to rootScope on module run. This one time binding will set it to title property in rootScope and each route will update this accordingly.

Here is the code to set it on module run:

angular.module("myApp").run(function ($rootScope, $state, $stateParams) {
    
     //set it here
     $rootScope.title = $state.current.title;
    
});

So this is the easy way to set your title property dynamically. If you have any question or feedback regarding this post please post in comments.

You may also like to see:

10 comments:

  1. Hello,

    Thanks for this article. But I wonder... How can you do this when your title is dynamic ? (name of the article you're consulting for example)

    ReplyDelete
    Replies
    1. thanks for liking! If you want to make title text dynamic than you can simply update $rootScope.title, when you get the article from service. As you recieved article assign its title to $rootScope.title. that's it.

      Delete
    2. I should have think about that by myself, thanks for the answer! ^^

      I'll use this system on my next project ;)

      Delete
    3. Zaheer, thank you for the example. I am a beginner with angularJS and I too am trying to dynamically change the title. I have product app where each time a product is clicked on the title needs to change to reflect the current product.

      I need help with this because when I use a facebook share button and the window pops up, it displays " {{product.title}} instead of the actual product title.

      You help would be much appreciated. Thank you!

      Delete
    4. You can solve it by using in title tag ng-bind-html="title" Facebook Share (see at top of article) instead of {{ }} this expression. If popup is within your site domain then you can update it otherwise default text will be shown.

      Delete
  2. Hi Zaheer,
    I am using a service to update titles. On my app.coffee page where should I create a controller to call the service-In the config part or in the run part?
    Also what should I use in the html page to bind it?
    eg: title ng-bing="service.title" is this correct?
    Thanks in advance.

    ReplyDelete
  3. Did you guys try ngTitle module? It allows to set title from routes, controller and templates. Check it out https://github.com/appmux/adhesive.js they have a demo there.

    ReplyDelete
  4. Firstly, thanks for this nice tip! =) However it can't work in Angular 1.4.5, but after this small change below now it works:


    ...
    angular.module('myApp').run(function ($rootScope, $state) {
    $rootScope.$on('$stateChangeSuccess', function () {
    $rootScope.title = $state.current.title;
    });
    });
    ...

    ReplyDelete
  5. Hi Zaheer, thanks this realy help me.

    ReplyDelete