Øyvind
Øyvind

Reputation: 139

Angularjs routing on an express 4.0 backend API

I have started an application where I use Express 4.0 server. I have set up the routes based heavily on a tutorial on scotch.io (http://scotch.io/tutorials/javascript/build-a-restful-api-using-node-and-express-4), builiding a backend api to serve the front end SPA (angularjs). Here is an extract of the backend router:

router.route('/users')
   .get(function (req, res) {
       User.find(function(err, users) {
          if (err) {
             res.send(err);
          }
          else {
             res.json(users);
          }
       });
   })

Further down

// home page route (http://localhost:8080)
router.get('/', function(req, res) {
   res.send('API ROOT');    
});

app.use('/api', router);

From the frontend i use just a get to get the users from the api:

$http.get('/api/users')
    .success(function(data) {
        $scope.users = data;
});

and the angular routes are set up like this:

.when('/', {
    templateUrl: 'views/home.html',
    controller: 'MainController'
})

.when('/users', {
    templateUrl: 'views/user.html',
    controller: 'UserController'
})

The index.html has a link to /users.

When starting the server and goint into localhost:8080 it loads fine, and clicking the users loads the user.html view and lists the users.

However, if i click refresh when browser is in localhost:8080/users

I get:

Cannot get /users

Is it a controller issue? Or is it a problem with backend routing?

Any feedback/suggestions would be very welcome!

Searching some more, I see that there are several sollutions that might fix this: Either on the frontend (angular routes part) adding this to the end:

// >>> redirect other routes to
otherwise({
    redirectTo: '/'
});

Or on the backend (after all your routes):

app.get('*', function(req, res){
    res.render('index.html');
});

Which sollution is better (or is it reccomended to use both...?)

Upvotes: 1

Views: 3088

Answers (1)

adamK
adamK

Reputation: 3889

You should use both.

You need to provide a catch-all / wildcard route to your express application such that any routes that are not explicitly matched will return the index page which will load Angular and allow your Angular routes to then take over. Note that this should always be your last route (they are parsed in order).

app.get('*', function(req, res){
    res.render('index.html');
});

Then in your Angular app you should have a default route to catch any un-matched routes on the client side. This route will come into effect if the application is already loaded but an unknown route is encountered whereas the server side solution above will handle any direct requests.

function($routeProvider) {
    $routeProvider.
      when('/', {
        templateUrl: 'home.html',
        controller: 'homeCtrl'
      }).
      otherwise({
        redirectTo: '/'
      });
  }]);

Upvotes: 3

Related Questions