14

I want to start using Angular's ui-router instead of ngRoute. Originally, my app config looked like

myApp.config(["$routeProvider",
    function($routeProvider) {
        $routeProvider
            .when("/search", {
                templateUrl: "partials/customerSearch.html"
            })
            .when("/home", {
                templateUrl: "partials/home.html"
            })
            .when("/login", {
                templateUrl: "partials/login.html",
                controller:  "LoginCtrl"
            })
            .otherwise({
                redirectTo: "/home"
            })
        ;
    }
]);

I swapped out the libraries, and changed the config. I understand I could still use $routeProvider, but that seems like a legacy workaround.

myApp.config(["$urlRouterProvider", "$stateProvider",
    function($urlRouterProvider, $stateProvider) {
        $urlRouterProvider
            .when("/search", "partials/customerSearch.html")
            .when("/home",   "partials/home.html")
            .when("/login",  "partials/login.html")
            .otherwise("/home")
        ;
        $stateProvider
            .state({
                name:        "customer",
                url:         "/customer/:username",
                templateUrl: "partials/customer.html"
            })
            .state({
                parent:      "customer",
                name:        "details",
                url:         "/details",
                templateUrl: "partials/customerDetails.html"
            })
        ;

    }
]);

This gives me errors that seem to indicate $digest is stuck in a loop. I suspect the .otherwise("/home") rule. Am I specifying the handlers correctly, as if they were template URLs?

If I comment-out the .when()s, nothing works except "/customer/:username". Do I have to have a state defined for every route? If so, what is the point of having both $urlRouterProvider and $stateProvider? Asked differently, what is each supposed to do?

nshew13
  • 3,052
  • 5
  • 25
  • 39
  • Kick ngRoute to the curb. Look @ the config in the demo plnkr list on ui-router github. Your .states don't have a controller listed, yet "/customer/:username" would call a $scope in a controller. – cheekybastard Feb 21 '14 at 23:25
  • I found this: http://plnkr.co/edit/u18KQc?p=preview. It shows a `controller` property, but the samples all look like mock controllers (anonymous functions). I tried using the name of one of my controllers, both quoted and not, but that didn't seem to work. Additionally, the app still doesn't seem to be routing. – nshew13 Feb 22 '14 at 03:31
  • I somehow missed the very clearly labeled "Controllers" section in the wiki: https://github.com/angular-ui/ui-router/wiki#wiki-controllers. Thanks for humoring me. I'm still not clear on what to do with `$urlRouterProvider`, or whether I need a state defined for each former route (also asked in your answer). – nshew13 Feb 22 '14 at 19:47
  • https://github.com/angular-ui/ui-router/wiki/URL-Routing#wiki-urlrouterprovider. – cheekybastard Feb 23 '14 at 02:32

2 Answers2

13

Here is a basic example, i made a while ago, with name-spaced controllers in ui-router config, & one nested route (2nd tab): http://plnkr.co/edit/2DuSin?p=preview

template: can be changed to templateUrl: to point at HTML file.

var app = angular.module('plunker', ['ui.bootstrap', 'ui.bootstrap.tpls','ui.router']);
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
    .state('state1', {
      url: "/",
      template: 'Hello from the first Tab!',
      controller: 'FirstCtrl',
      data:{}
    })
    .state('state2', {
      url: "/route2",
      template: 'Hello from the 2nd Tab!<br>' +
                '<a ui-sref="state2.list">Show List</a><div ui-view></div>',
      controller: 'SecondCtrl',
      data: {}
    })
      .state('state2.list', {
        url: '/list',
        template: '<h2>Nest list state</h2><ul><li ng-repeat="thing in things">{{thing}}</li></ul>',
        controller: 'SecondCtrl',
        data: {}
      });
});

controllers:

app.controller('FirstCtrl', ['$scope', '$stateParams', '$state',  function($scope,$stateParams,$state){

}]);

app.controller('SecondCtrl', ['$scope', '$stateParams', '$state', function($scope,  $stateParams, $state){
    $scope.things = ["A", "Set", "Of", "Things"];
}]);
cheekybastard
  • 5,535
  • 3
  • 22
  • 26
  • So, do I need a state for every "page"/"view", where I used to have a route? Does the $urlRouterProvider serve mainly as an alias or symlink? Final Q: How can I have optional parameters, so that `/search` and `/search/:fn/:ln` go to the same view? – nshew13 Feb 22 '14 at 19:58
  • Yes, do a new .state for each URL (& nest of URL), its has similar abilities/uses as route, but has more super powers & works at an higher abstraction of "state". Nested state like `/search/:fn/:ln` will go to the same view if `.state` url is set as `url: ""` – cheekybastard Feb 23 '14 at 02:26
  • I'm still not clear on `$urlRouterProvider` nor the "optional params", but I think the latter, at least, is a separate beast (http://stackoverflow.com/q/21977598/356016). Thank you for your help. – nshew13 Feb 24 '14 at 01:59
  • 1
    With `urlRouterProvider.otherwise` if someone typo/misspells an URL they can be redirect to 404 page or bounced to root URL. `data: {}` can be used for Objects to generate page tile, etc, like so: `data:{ pageTitle: 'Search' }` – cheekybastard Feb 24 '14 at 06:04
0

This should work out for you. The otherwise function is part of the $urlRouteProvider service. If you run into issues, please view the tutorials on how to define the object that is used as a parameter for the $stateProvider.state() function. Here I just focused on where to put the otherwise route.

myApp.config(['$stateProvider','$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {

    $stateProvider
        .state({
            name:        'customer',
            url:         '/customer/:username',
            templateUrl: 'partials/customer.html',
            controller: 'YourCtrl'
        })
        .state({
            parent:      'customer',
            name:        'details',
            url:         '/details',
            templateUrl: '/partials/customerDetails.html',
            controller: 'YourCtrl'
        });

     $urlRouteProvider.otherwise('home');
}

]);

Dun
  • 449
  • 3
  • 14