8

Examples slugs in server database accessible through API:

{slug: "john-smith",type: "user"}
{slug: "microsoft-technologies",type: "company"}

scenario 1 : user view & controller : http://localhost/john-smith

.state('user', {
    url: '/:user',
    templateUrl: 'partial-user.html',
    controller: 'userCtrl'
})

scenario 2 : company view & controller : http://localhost/microsoft-technologies

.state('company', {
    url: '/:company',
    templateUrl: 'partial-company.html',
    controller: 'companyCtrl'
})

Now I want to make make a dynamic state based the slug getting from API Call to the server.

I written a imaginary code. But I'm not getting way to achieve

// Example URL http://localhost/john-smith
.state('hybrid', {
    // /john-smith
    url: '/:slug',
    templateUrl: function () {
        return "partial-"+type+".html"
    },
    controllerProvider: function (rt) {
        return type+'Controller'
    },
    resolove: {
        type: function ($http, $stateParams) {
            $http.get({
                method: "GET",
                url: "http://localhost/api/" + $stateParams.slug
            }).success(function(response, status, headers, config){
                //response = {slug: "john-smith",type: "user"}
                return response.type
            })
            return 
        }
    }    
})

1 Answer 1

10

There is a working plunker.

It comes from similar issue: AngularJS ui-router - two identical route groups

In case, I do understand your aim properly, this would be the adjusted state definition (I just skipped the $http and server response part, just working with passed parameter):

.state('hybrid', {
    // /john-smith
    url: '/{slug:(?:john|user|company)}',
    templateProvider: ['type', '$templateRequest',
      function(type, templateRequest) 
      {
        var tplName = "tpl.partial-" + type + ".html";
        return templateRequest(tplName);
      }
    ],
    controllerProvider: ['type',
      function(type) 
      {
        return type + 'Controller';
      }
    ],
    resolve: {
      type: ['$http', '$stateParams',
        function($http, $stateParams) {
          /*$http.get({
            method: "GET",
            url: "http://localhost/api/" + $stateParams.slug
        }).success(function(response, status, headers, config){
            //response = {slug: "john-smith",type: "user"}
            return response.type
        })*/
          return $stateParams.slug
        }
      ]
    }
})

One change is the resolove : {} became: resolve : {}. Another is fixture of the controller def (rt vs type). And also, we do profit from built in features templateProvider and $templateRequest (similar here: Angular ui.router reload parent templateProvider)

check that in action here

EXTEND, including the $http part (extended plunker)

Let's adjust (for plunker purposes) the server part to return this info as data.json:

{
 "john-smith": {"type": "user"},
 "lady-ann": {"type": "user"},
 "microsoft-technologies" : {"type": "company" },
 "big-company" : {"type": "company" },
 "default": {"type" : "other" }
}

And these links:

<a href="#/john-smith">
<a href="#/lady-ann">

<a href="#/microsoft-technologies">
<a href="#/big-company">

<a href="#/other-unknown">

Will be easily managed by this adjusted state def:

  .state('hybrid', {
    // /john-smith
    url: '/:slug',
    templateProvider: ['type', '$templateRequest',
      function(type, templateRequest) 
      {
        var tplName = "tpl.partial-" + type + ".html";
        return templateRequest(tplName);
      }
    ],
    controllerProvider: ['type',
      function(type) 
      {
        return type + 'Controller';
      }
    ],
    resolve: {
      type: ['$http', '$stateParams',
        function($http, $stateParams) {
          return $http.get("data.json")
            .then(function(response){
              var theType = response.data[$stateParams.slug]
                  ||response.data["default"]
              return theType.type
            })
        }
      ]
    }
  })

Check that updated stuff here

Sign up to request clarification or add additional context in comments.

5 Comments

I want return type based on http response& http request based on $stateParams.slug. From http response i can get template/controller name
This is just a consumption of the $http result... which I skipped,(because not having the server part in the plunker)... But that is easy bit. I did the rest for you.. controllers, templates... you will just call server, recieve response and pass it instead of my type result.. as object
but how to pass promise from http is my doubt. Please use setTimeout instead of $http. see here plnkr.co/edit/UngzlI2g9DSHVM2CKfwC?p=preview [Plnkr]
I extended example and make it working with $http (a bit simplified then real server, but...working ;) Hope this will give you all the answers.. Enjoy UI-Router
Do you have the same solution but for a most recent version of angular ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.