AJeezy9
AJeezy9

Reputation: 1289

Can I pass a variable into the controller using UI-Router & ui-sref?

I was wondering if it was possible to pass multiple variables through the UI-Router to be used in a state's controller.

In the HTML, I have

<li class="blist-item grid-loader" ng-repeat="item in items">
    <a ui-sref="item({ id: {{item.$id}} })"><h3>{{item.title}}</h3></a>
</li>

And in the configuration, I have:

.state('item', {
        url: '/item/:id',
        templateUrl: 'templates/single/single-main.html',
        controller: function($scope, $stateParams){
        $scope.item.$id = $stateParams.id;
    }
})

Now, the above configuration works, but the problem is that each item's unique ID is an incomprehensible string that leaves me with links such as "/item/-sds43sd_23s".

What I am trying to figure out is:

(1) how to have the URL be directed to the item title,

(2) while also using the item's ID as the primary method for getting the item object's data.


Is there a way I can pass both variables (the item's ID & the item's title) through to the router?

Upvotes: 2

Views: 197

Answers (1)

Radim K&#246;hler
Radim K&#246;hler

Reputation: 123861

I would say, there is a solution for your issue. This Q & A should solve it: How to implement path aliases in ui-router. There is a link to that working example.

We would need this state definition (exactly as in above snippet) which does not restrict id anyhow (e.g. Regex Parameters {id:[0-9a-fA-F]{1,8}} this would avoid passing title...)

.state('item', {
    url: '/item/:id', // no restrcitions, this is what we need
    ...

Next step is to have a service which is able to get ID by title

.factory('ItemSvc', ...
  // some service, converting title into ID
  ...
  var getIdByTitle = function(title){
     // some how get the ID for a Title
     ...
  }

Finally, we will use UI-Router feature $urlRouterProvider - .when()

$urlRouterProvider.when(/item\/[a-zA-Z\-]+/,
  function($match, $state, ItemSvc) {

    // get the Title 
    var title = $match.input.split('item/')[1];
    // get some promise resolving that title
    // converting it into ID
    var promiseId = ItemSvc.getIdByTitle(title);

    promiseId.then(function(id){

      // once ID is recieved... we can go to the detail
      $state.go('item', {id: id}, {location: false}); 
    })

    // essential part! this will instruct UI-Router, 
    // that we did it... no need to resolve state anymore
    return true;
  }
);

Check the example in action here

Upvotes: 1

Related Questions