Your SlideShare is downloading. ×
  • Like
Angular JS Routing
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Angular JS Routing

  • 4,383 views
Published

Talk given at AngularJS meeting in London on 13 August 2013.

Talk given at AngularJS meeting in London on 13 August 2013.

Published in Business , Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
4,383
On SlideShare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
36
Comments
0
Likes
2

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. AngularJS Application Routing Tuesday, 13 August 13
  • 2. Routes: REST/Servers v. Client Apps •HTTP is stateless, so routes help define application state. •REST emphasizes semantic routes. (GET  /user/dave) But... •There is more state than can be represented in a route (user state, session state) •Client-side apps don’t actually need routes to work (e.g. many jquery-based apps) Tuesday, 13 August 13
  • 3. Why use routes? Routes: •Make the back button work as expected •Make major (page-like) transitions clear •Allow easy linking •Make testing easier •Encapsulate some state Tuesday, 13 August 13
  • 4. From Angular-Phonecat: angular.module('phonecat',  ['phonecatFilters',   'phonecatServices']).    config(['$routeProvider',  function($routeProvider)  {    $routeProvider.            when('/phones',  {templateUrl:  'partials/phone-­‐ list.html',      controller:  PhoneListCtrl}).            when('/phones/:phoneId',  {templateUrl:  'partials/ phone-­‐detail.html',  controller:  PhoneDetailCtrl}).            otherwise({redirectTo:  '/phones'}); }]); Basic Routes Tuesday, 13 August 13
  • 5. .when('/phones/:phoneId',  {templateUrl:  'partials/phone-­‐ detail.html',  controller:  PhoneDetailCtrl}) :phoneId stored in $route.current.params, available controller and resolve functions. Basic Routes Tuesday, 13 August 13
  • 6. Realistic Routes Structure / – welcome /stream – logged-in home /login – log-in /signup – signup /user/:username – user profile /explore – explore tags /settings – user settings /new-spark – create spark page /spark/cluster?sparkName=&tagName – spark cluster page /search – search /spark/:username/:slug – spark page ...and 11 more routes Tuesday, 13 August 13
  • 7. Resolve for Data Each item in the resolve map: •Runs before the controller is instantiated •Provides its value to the controller •If it is a promise: •It will (wait to) resolve the promise first •If the promise is rejected, the route errors Using resolve for database objects means •No UI flicker as promises are resolved •Controllers can assume objects exist •Tests are cleaner: pass in data object explicitly Tuesday, 13 August 13
  • 8. Resolve for Data when('/tag/:tagName',  {  resolve:  {    tagResolve:  ['tag','$route',      function  (tagService,  $route)  {        return  tagService.get($route.current.params.tagName);    }],    sparkClustersResolve:  ['sparkCluster','$route',      function  (sparkClusterService,  $route)  {        return   sparkClusterService.getSparkClustersByTag($route.current.p arams.tagName); }]}}); Tuesday, 13 August 13
  • 9. Resolve for Data Treat your resolved object like a dependency in the controller: .controller('ViewTagCtrl',  ['$scope','$routeParams','tag', 'sparkCluster','log','$location','user','header','sparkClu stersResolve','tagResolve','currentUserResolve' Use a ‘route controller’, not a ‘view controller’ (ng-­‐controller): when('/tag/:tagName',  {  controller:  'ViewTagCtrl'  }) Tuesday, 13 August 13
  • 10. Resolve for Rules Rejected Promises cause routes to fail. You can use this to make rules for the route like ACLs or prerequisites. Reject a promise to cause a route to fail. Using resolve to make rules means: •All resolution rules must pass before route succeeds and controller is instantiated. •Common ACLs (logged-in) specified in routes, not each controller or service •Can redirect the user to an appropriate page (also can do user-facing error) Tuesday, 13 August 13
  • 11. when('/tag/:tagName',  {  resolve:  {    mustAuth  :  ['route',  function  (routeService)  {        return  routeService.mustAuth('/');}]}]}}); routeService.mustAuth  =  function  (redirectTo)  {  var  authDeferred,  p;  authDeferred  =  $q.defer();  p  =  userService.getCurrent();  p.then(function  (currentUser)  {    if  (angular.isUndefined(currentUser._id))  {      $location.url(redirectTo);      authDeferred.reject();    }  else  {  authDeferred.resolve(mustAuth);  }});  return  authDeferred.promise; }; Resolve for Rules Tuesday, 13 August 13
  • 12. Resolve for Route-Specific UI Resolve can pass route-specific configuration to another service that affects the UI, like “show a promo”. Using resolve to control UI means: •Routes handle turning on and off UI elements •Route Controllers don’t need to worry about configuring site- wide UI elements like headers, promos, menus *There are other (possibly better) options for this, including having the UI controller listen to RouteChangeSuccess events. Tuesday, 13 August 13
  • 13. when('/tag/:tagName',  {  resolve:  {    makeSparkPromo:  ['promo',      function  (promoService)  {        return  promoService.route('makeSparkPromo',  true); }]}}}); Resolve for Route-Specific UI Tuesday, 13 August 13
  • 14. Testing Routes Midway Normally you can only test routing with E2E testing, slowly. Midway Testing (see Year Of Moo) is basically big unit testing. Use a router helper, which has routeDefined, getRoute. Midway testing routes means unittesting-like speed and E2E-like app setup. Tuesday, 13 August 13
  • 15. ROUTER.when('tag',  '/tag/:tagName',  {  templateUrl:  '/partials/tag/tag-­‐detail.html',  controller:  'ViewTagCtrl' }); ROUTER.otherwise({  redirectTo  :  '/' }); ROUTER.install($routeProvider); Testing Routes Midway–Router Helper Tuesday, 13 August 13
  • 16. before(function(done)  {  test  =  new  ngMidwayTester();  test.register('App',  done); }); it('should  have  a  route  to  a  tag  page',  function()  {        expect(  ROUTER.routeDefined('tags')).to.equal(true);  var  url  =  ROUTER.routePath('tags',  {tagName:  ‘cooking’);  expect(url).to.equal('/tag/cooking'); }); Testing Routes Midway–Testing Tuesday, 13 August 13
  • 17. Recap The phonecat way (sticking everything under app) is unscalable. Angular’s route system is flexible and powerful, if you take advantage of resolve and promises. Using helper functions and midway testing means you can unit test more things. The less you rely on E2E testing, the better. Tuesday, 13 August 13
  • 18. Other Good Ideas Others have addressed the same problems in a more reusable way. Angular UI router: use ‘state’ instead of routes. Seems good. Worth considering if you start fresh. Angular App: great example of well-designed app, but maybe hard to follow for a novice. Interesting crudRouteProvider implementation. Tuesday, 13 August 13