ssl
ssl

Reputation: 125

Angular JS use one view for two two URLS

How can I write following two views together as one - both of them sharing the same contrl, same templateurl, same url with different params?

$stateProvider.state('user-view', {
  params: {
    selectedTab: 0
  },
  templateUrl: './resources/user-view.html',
  url: '/user-view/:userId',
  controller: 'useriewCtrl',
  resolve: {
    user: ['userService', '$stateParams', function (userService,
      $stateParams) {
      return renewalService.getUser($stateParams.userId);
    }],
    selectedTab: ['$stateParams', function ($stateParams) {
      if ($stateParams.selectedTab != null) {
        return $stateParams.selectedTab;
      }
      return 0;
    }]
  }
});

$stateProvider.state('user-view', {
  params: {
    selectedTab: 0
  },
  templateUrl: './resources/user-view.html',
  url: '/user-view/:dataeofbirth/:address',
  controller: 'useriewCtrl',
  resolve: {
    user: ['userService', '$stateParams', function (userService,
      $stateParams) {
      return renewalService.getUser($stateParams.dataeofbirth,
        $stateParams.address);
    }],
    selectedTab: ['$stateParams', function ($stateParams) {
      if ($stateParams.selectedTab != null) {
        return $stateParams.selectedTab;
      }
      return 0;
    }]
  }
});

Upvotes: 4

Views: 69

Answers (2)

pranavjindal999
pranavjindal999

Reputation: 3047

You can take params as part of query string instead of part of url and you need to do this as ui-router would need keys to know what is userId and what is dob and address.

$stateProvider.state('user-view', {
  params: {
    selectedTab: 0
  },
  templateUrl: './resources/user-view.html',
  url: '/user-view?userId&dataeofbirth&address',
  controller: 'useriewCtrl',
  resolve: {
    user: ['userService', '$stateParams', function (userService,
      $stateParams) {
        if($stateParams.userId)
            return renewalService.getUser($stateParams.userId);
        else
            return renewalService.getUser($stateParams.dataeofbirth, $stateParams.address);
    }],
    selectedTab: ['$stateParams', function ($stateParams) {
      if ($stateParams.selectedTab != null) {
        return $stateParams.selectedTab;
      }
      return 0;
    }]
  }
});

Demo: http://plnkr.co/edit/ZAIWpuFHxclY9hfpfhQC?p=preview

Upvotes: 1

Maxim Shoustin
Maxim Shoustin

Reputation: 77904

State url gives you ability to provide optional fields.

So you can merge:

  • '/user-view/:userId'
  • '/user-view?userId&dataeofbirth&address'

to something like:

url: '/user-view/:userId?/:dataeofbirth?/:address?'

However the main disadvantage of this approach, the $state doesn't know how to populate 3 optional arguments.

so if we will write:

  • /user-view/userId12 - OK
  • /user-view/dataeofbirth3/address4 - here we will get:

    userId = dataeofbirth3 and dataeofbirth = address4

Demo that demonstrates the problem in Plunker

So we can just write:

url: '/user-view/:arg1?/:arg2?/:arg3?' 

or with usage of squash:

 url: '/user-view/:arg1/:arg2/:arg3',
 params: {
           arg1:       {squash: true, value: null},
           arg2: {squash: true, value: null},
           arg3:      {squash: true, value: null}
         } 

$stateProvider.state('user-view', {
  params: {
    selectedTab: 0
  },
  templateUrl: './resources/user-view.html',
  url: '/user-view/:userId?/:dataeofbirth?/:address?'
  controller: 'useriewCtrl',
  resolve: {
    user: ['userService', '$stateParams', function (userService,
      $stateParams) {

      if($stateParams.arg1 && !$stateParams.arg2){// we have only userId
         return renewalService.getUser($stateParams.arg1);
       }
      else if ($stateParams.arg1  && $stateParams.arg2){
          renewalService.getUser($stateParams.arg1,
    $stateParams.arg2);
      }
       else{
         // other fallback
       }          
    }],
    selectedTab: /* ... */
  }
});

Upvotes: 0

Related Questions