TIMBERings
TIMBERings

Reputation: 768

Node Express isn't Redirecting, but instead returning a string

I'm new to node and angular, trying to figure out how to redirect on a bad request. Node is essentially a proxy to a RESTful API. Currently, weather.error is being populated as Bad Request. Redirecting to /public/400.html

Server call:

app.get('/currently', function(request, response) {
    var options = {
        exclude: 'minutely,hourly,daily,flags,alerts'
    };
    forecast.get(request.query.latitude, request.query.longitude, options, function(err, res, data) {
        if (err) {
            console.log('Error in request. \nLatitude: ' + request.query.latitude + '\nLongitude: ' + request.query.longitude);
            var status = data.split('<title>')[1].split(' ')[0]
            if (status === '404') {
                response.status(400).sendFile(__dirname + '/public/images/404/404-' + Math.floor((Math.random() * 3) + 1) + '.jpg');
            } else if (status === '400') {
                response.redirect(400, '/public/400.html');
            } else {
                response.status(parseInt(status)).end();
            }
        } else {
            response.send(JSON.stringify(data));
        }
    });
});

Controller:

angular.module('myApp.weather', [
    'ui.router'
])
  .config(function($stateProvider) {
      $stateProvider
          .state('weather', {
              url: '/weather',
              templateUrl: 'app/weather/weather.tmpl.html',
              controller: 'WeatherController as weather'
          });
  }).controller('WeatherController', function($http, $location) {
      var weather = this;
      weather.latitude = '';
      weather.longitude = '';

      weather.getCurrentWeatherByLatLon = function(latitude, longitude) {
          $http.get('/currently?latitude=' + latitude + '&longitude=' + longitude)
              .success(function(data, status, headers, config) {
                  weather.data = data;
              })
              .error(function(data, status, headers, config) {//I don't think this should be necessary if I'm handling it in the sever
                  weather.error = data;
                  if(data.indexOf('Bad Request') >= 0) { 
                      console.log('Bad Request')
                      $location.path('/public/400.html'); //doesn't navigate anywhere
                  }
              })
              ;
      };

-------------------------------EDIT-------------------------

I've changed my server call to:

app.get('/currently', function(request, response) {
    var options = {
        exclude: 'minutely,hourly,daily,flags,alerts'
    };
    forecast.get(request.query.latitude, request.query.longitude, options, function(err, res, data) {
        if (err) {
            console.log('Error in request. \nLatitude: ' + request.query.latitude + '\nLongitude: ' + request.query.longitude);
            var status = data.split('<title>')[1].split(' ')[0]
            response.status(status).send();
        } else {
            response.send(JSON.stringify(data));
        }
    });
});

and the function in my controller to:

weather.getCurrentWeatherByLatLon = function(latitude, longitude) {
    $http.get('/currently?latitude=' + latitude + '&longitude=' + longitude)
        .success(function(data, status, headers, config) {
            weather.data = data; // this callback will be called asynchronously
                // when the response is available
        })
        .error(function(data, status, headers, config) {
            weather.error = status
            if (status == 400) {
                console.log('in 400');
                $location.url('/public/400.html');
            } else if (status == 404) {                              
                console.log('in 404');
                $location.url('/public/404.html');
            }
        });
};

Upvotes: 1

Views: 447

Answers (2)

Matteo
Matteo

Reputation: 39390

I suggest you yo use the url method of the locationProvider service, this permit to pass the control of the flow to a controller managed route: yes you must implement this route with a controller.

Try with

$location.url('/public/400.html');

instead of

$location.path('/public/400.html');

Another option for serve static content is to use the window service as:

Try with

$window.location.href ='/public/400.html';

instead of

$location.path('/public/400.html');

Benefit to use this instead of the standard javascript window object (from the docs):

A reference to the browser's window object. While window is globally available in JavaScript, it causes testability problems, because it is a global variable. In angular we always refer to it through the $window service, so it may be overridden, removed or mocked for testing.

Hope this help

Upvotes: 0

Emil Ingerslev
Emil Ingerslev

Reputation: 4775

You can't redirect ajax calls. A redirect made with response.redirect(400, '/public/400.html') is just a HTTP response with a "special" header, and this isn't supported by ajax.

If you wan't to handle problems with the request, return a status or likewise and handle it on the client.

Upvotes: 3

Related Questions