Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS Restful Routing

I'm trying to structure my app using the Restful/Ruby convension /<resource>/[method]/[id]. How I've done it previously when using a server-side MVC framework like CodeIgniter was to dynamically route based on the URI:

ex.

www.foo.com/bar/baz/1

The app would then use method baz in controller/class bar and return views/bar/baz.php (populated with data from bar->baz)

I would like to do the same in Angular, but I'm not sure if it supports this (and if it does, I'm not sure exactly how to go about it). At the moment I'm using $routeProvider's when method to specify each case. $location.path() looks like it might have what I need, but I don't think I can use it in app.js (within config()).

What I'd like to do is something like this:

.config([
  '$routeProvider', function($routeProvider) {
    $routeProvider
    .when(//<resource> controller exists
      resource+'/'+method, {
        "templateURL": "views/" + resource + "/" + method + ".html",
        "controller":  resource
      }
    ).otherwise({ "redirectTo":"/error" });
  }
]);

And the router automatically calls the appropriate method.

EDIT Also, why does $routeProvider freak out when I specify when('/foo/bar', {…}) ?

EDIT 2 Per Lee's suggestion, I'm looking into doing something like this:

$routeProvider
  .when(
    '/:resource/:method/:id', {
      "templateUrl": function(routeParams){
        var path = 'views/'+routeParams.resource+'/';
        return ( typeof routeParams.method === 'undefined' ) ?
          path+'index.html' : path+routeParams.method+'.html';
      },
      "controller": RESOURCE
  })
  .otherwise({redirectTo: '/error'});

I noticed the following in $routeProvider's doc:

screenshot from Dash. full text below

templateUrl – {string=|function()=} – path or function that returns a path to an html template that should be used by ngView.

If templateUrl is a function, it will be called with the following parameters:

• {Array.<Object>} - route parameters extracted from the current $location.path() by applying the current route

Edit: The option to set templateUrl to a function is part of the unstable 1.1.2 build: #1963 (but it doesn't work as of 2013-02-07).

There is a dicussion about adding this functionality on AngularJS's Github: #1193 #1524, but I can't tell if it was actually implemented (in the docs from Dash quoted above, it looks like it has been, and the docs on the site haven't been updated yet).

EDIT 3 To clarify what I want to happen (per lee's request), in simplest terms, I would like to go to www.foo.com/index.html#/people

Angular should use controller people, automatically call its index method, and should serve up

./views/people/index.html
./views/people/map.html

Also, if I go to www.foo.com/index.html#/people/map

Angular should use the people controller again, but this time automcatically call its map method and serve up …map.html (because map was specified in the url)

./views/people/index.html
./views/people/map.html

Then, if I go to

www.foo.com/index.html#/widgets

Angular should serve up

./views/widgets/index.html
./views/widgets/details.html

The code for the router should be very generic—I shouldn't have to specify a .when() for every route.

like image 451
Jakob Jingleheimer Avatar asked Feb 05 '13 21:02

Jakob Jingleheimer


People also ask

What is RESTful routing?

A RESTful route is a route that provides mapping from HTTP verbs (get, post, put, delete, patch) to controller CRUD actions (create, read, update, delete). Instead of relying solely on the URL to indicate what site to visit, a RESTful route depends on the HTTP verb and the URL.

What is REST API in AngularJS?

The RESTful functionality is provided by AngularJS in the ngResource module, which is distributed separately from the core AngularJS framework. Since we are using npm to install client-side dependencies, this step updates the package. json configuration file to include the new dependency: package.

What is ngRoute AngularJS?

AngularJS ngRoute module provides routing, deep linking services and directives for angular applications. We have to download angular-route. js script that contains the ngRoute module from AngularJS official website to use the routing feature. You can also use the CDN in your application to include this file.


1 Answers

Thinking about this a little more. You could just have a single controller for those generic CRUD/REST type operations. Then load the templates using the resource and view parameters.

  • Create
    • #/foo/create/0
    • This has it's own form template "/views/foo/create.html" and the 0 os just there for a placeholder.
    • on submit you would call a method on the controller ng-click="save()" which would post to the server at POST "/rest/foo".
  • Read
    • #/foo/view/1
    • Again the template "/views/foo/view.html" is just a view of the data
    • You can call a service method to get the data from your server using GET "/rest/foo/1"
  • Update -#/foo/edit/1
    • Could use the same template as create or you could use a different one "/views/foo/edit.html" if you like.
    • Also pull the data using GET "/rest/foo/1"
    • Submit the data using PUT "/rest/foo/1"
  • Delete
    • #/foo/delete/1
    • service method would call DELETE "/rest/foo/1"
    • I don't think you want a hash for this, but you could use one because the controller could actually do a verification or anything you like to confirm the deletion. Maybe have a view called "/views/foo/delete.html" that asks if you want to delete the record. Then you could have ng-click="delete(itemid)" on a button somewhere that deletes the item via ajax.

All this could be done using a single controller/service and dynamically generating the service and view urls.

Anything that's custom you would need a custom controller and custom routes and service methods for. I could probably throw together an example, but not tonight.

like image 164
Lee Avatar answered Oct 02 '22 08:10

Lee