Setting up states from a json file in angularjs applications


Imagine a this simple angularjs application using angular-ui-router:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Example</title>
    <script src="bower_components/angular/angular.js"></script>
    <script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
    <script src="js/app.js"></script>

</head>
<body ng-app="App" ng-controller="MainController">

<div ui-view></div>
</body>
</html>

angular.module('App', ['ui.router'])

    .config(function ($stateProvider, $urlRouterProvider, routerProvider) {
        $stateProvider
            .state('home', {
                url: '/home',
                templateUrl: 'templates/home.html'
            });

        $urlRouterProvider.otherwise('/home');
    })

    .controller('MainController', function ($scope, router) {
        $scope.reload = function() {
            router.setUpRoutes();
        };
    })
;

We’ve defined only one state called “home”. If we need more states we just add more within config() function. In this post we’re going to try to add more states from a json file instead of hardcode the states within the code.

Let’s create our json file with the states definitions:

{
    "xxx": {
        "url": "/xxx",
        "templateUrl": "templates/xxx.html"
    },

    "yyy": {
        "url": "/yyy",
        "templateUrl": "templates/yyy.html"
    },

    "zzz": {
        "url": "/zzz",
        "templateUrl": "templates/zzz.html"
    }
}

Now our application looks like this:

angular.module('App', ['ui.router', 'Routing'])

    .config(function ($stateProvider, $urlRouterProvider, routerProvider) {
        $stateProvider
            .state('home', {
                url: '/home',
                templateUrl: 'templates/home.html'
            });

        $urlRouterProvider.otherwise('/home');

        routerProvider.setCollectionUrl('js/routeCollection.json');
    })

    .controller('MainController', function ($scope, router) {
        $scope.reload = function() {
            router.setUpRoutes();
        };
    })
;

As we can see now we’re using ‘Routing’

angular.module('Routing', ['ui.router'])
    .provider('router', function ($stateProvider) {

        var urlCollection;

        this.$get = function ($http, $state) {
            return {
                setUpRoutes: function () {
                    $http.get(urlCollection).success(function (collection) {
                        for (var routeName in collection) {
                            if (!$state.get(routeName)) {
                                $stateProvider.state(routeName, collection[routeName]);
                            }
                        }
                    });
                }
            }
        };

        this.setCollectionUrl = function (url) {
            urlCollection = url;
        }
    })

    .run(function (router) {
        router.setUpRoutes();
    });

‘Routing’ provides us a provider called ‘router’ that fetch the json file and build the states.

That’s a proof of concept.
There’s a couple of problems (please tell me if you know how to solve them):

  • As far as we’re loading states from a http connection, angular application don’t have all the states when it starts, so we need to create at least the first state with the “old style”
  • We can reload states with the application running. We also can add new states, but we cannot modify the existing ones.

you can see the one example project within my github account.

About these ads

About Gonzalo Ayuso

Web Architect specialized in Open Source technologies. PHP, Python, JQuery, Dojo, PostgreSQL, CouchDB and node.js but always learning.

Posted on June 30, 2014, in AngularJS, js, Technology and tagged , , . Bookmark the permalink. 15 Comments.

  1. What about resolve parameter?

  2. What problem does this way of configuring routes solve?

    • The idea behind this experiment is reload routes dynamically. Imagine a phonegap/cordova application. If add one route I need to redeploy the app. If routes can be loaded from a remote url, I can send a websocket/pushNotification and reload the routes. Another purpose is to write routes in a clean template. I’ve got a PHP/Symfony background and that’s the way Sf does.

      • Interesting. I haven’t done any phonegap apps, so I might be missing something… but, if you add new routes, wouldn’t you also be adding views/controllers/models to correspond to the new route (essentially, a new feature)? Wouldn’t this require you to redeploy the app anyway?

      • it depends. For example views can be set with templateUrl (and the url can be a remote server url). When we work with phonegap/cordova applications we must take into account that resources are inside our device. One simple change within our main index.html file means redeploy the application. And redeploy means that we cannot assert if user upgrades the application or not. Every change we do without redeploy may be good.

        Anyway this post is just an experiment. An experiment playing in the edge of cordova application. Something like ¿Is is possible to that? Let’s try it

  3. great solution.

    Needed something too, where you could only see their routers after logged

    This solution could be used in production?

    I do not understand how to use ui router Resolve to this case

    • Be careful “hide” routes to unlogged users may not be a good solution. It sounds like “security through obscurity”.

      I’m not using it in production. It’s just a prof of concepts.

  4. I’m trying solution but loading the routes from the db. However it’s not working for deep linking. For example (using your example routes) I can go to the url “/home” then navigate to “/xxx”. This works but when I reload the page I am redirected back to “/home”. Is it the same for you?

    I’m starting to thing the right way may be to write your own route service to use instead of ui router.

    • Yes I don’t know how to solve it yet. That’s because initial routes are created within config() and extra routes are loading in run().

  5. great solution, but I have problem on ui-sref. I can have only home link, the links from json file can’t be generated using ui-sref directive.

    • I don’t understand when you say “links from json file can’t be generated using ui-sref directive”. Do you have an example?

  1. Pingback: Configurando estados de um arquivo json em aplicações AngularJS -

  2. Pingback: Configurando estados de um arquivo json em aplicações AngularJS -

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 992 other followers

%d bloggers like this: