How to best handle errors in ExpressJS POST routes - angularjs

I am currently struggling with best practices for error handling in ExpressJS routes, particularly POST routes.
I have set up the default middleware error handling and I am using return next(err); in case of any errors. This works fine for all errors in GET routes.
However, what is the best practice to handle errors in the other route types, in particular POST routes?
On the front end, I am using AngularJS and I am posting using $http. When using return next(err); in the POST route, the .error(function(data,status,headers,config) of $http is called (AngularJS) and I receive the whole html error page inside data variable.
What I am looking for is a redirect for the user to the general error page through the ExpressJS middleware in case the client-side should not handle this error. This way, I could also do my error handling and logging at one single place.
So, my current idea: In POST routes, simply do return res.status(500).send({err: err}); In case the application cannot recover, then use a redirect on client side with AngularJS to a general error page. However, I would prefer to use the ExpressJS middleware to have a central place to handle errors.
I appreciate any help or pointers to best practice articles!
For reference, the (standard) error middleware function looks like this:
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('shared/error/error', {
message: err.message,
error: err
});
});

If you're using an angular $http method to GET or POST to your server, you should be returning JSON data back to the app to parse. For example, your route:
app.get('/example', function(req, res) {
getSomeData()
.then(function(data) {
res.status(200).json(data);
}, function(err) {
res.status(400).json(err);
});
});
In your angular service, you can create a method that returns the route's data in a promise:
angularApp.service('DataService', function($http) {
this.getData = function() {
return $http.get('/example')
};
});
Then use the service in your controller like this:
angularApp.controller('MyController', function($scope, DataService) {
DataService.getData()
.then(function(response) {
$scope.data = response.data;
}, function(err) {
showErrorMessage(err.statusText);
});
});

Related

Angular - 404 HTTP Interceptor

Whenever my node server returns a 404 error, I want this to be intercepted by my Angular app and the user directed to a certain route.
I'm trying to build a simple interceptor to do this however it doesn't seem to return anything.
Any pointers on why this code won't print anything when the 404 is coming in (I've confirmed this by looking at the page header):
And the code:
.config(function($httpProvider) {
//Ignore this authInceptor is for saving my JWT's
$httpProvider.interceptors.push('authInterceptor');
//This is the one I'm having issue with
$httpProvider.interceptors.push(function myErrorInterceptor($window, $location) {
return {
requestError: function(res){
if (res.status === 404) {
console.log('You're In - Now do some more stuff')
}
return res;
}
}
})
})
UPDATE:
So in addition to that, i've realised on my node side - i have
//This section is to handle Angular HTML5Mode Urls
//Have to rewrite all your links to entry point of your application (e.g. index.html)
app.get('/*', function(req, res) {
res.sendFile(__dirname + '/site/index.html')
});
So another issue here is - that app.get('/*' won't be bale to distinguish between whats allowed as per Angular routes - so how do i get it be aware of that? (Don't want something an array where i duplicate code)
I believe the problem is that you are hooking into requestError instead of responseError. Try the following:
.config(function($httpProvider) {
//Ignore this authInceptor is for saving my JWT's
$httpProvider.interceptors.push('authInterceptor');
//This is the one I'm having issue with
$httpProvider.interceptors.push(function myErrorInterceptor($window, $location) {
return {
responseError: function(res){
if (res.status === 404) {
console.log('You're In - Now do some more stuff')
}
return res;
}
}
})
});

angularjs express get data back via $http post

I am newbie in firebase admin SDK and trying to get it work on my angularjs app, using and following the steps here and this here:
I have correctly setup my firebase admin SDK and initialized it like this in server.js file on my node server:
var admin = require("firebase-admin");
var serviceAccount = require("path/to/serviceAccountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://<DATABASE_NAME>.firebaseio.com"
});
app.post('/.firebase-user', function (req, res, nex) {
admin.auth().getUser(req.body.uid)
.then(function (userRecord) {
// See the tables below for the contents of userRecord
console.log("Successfully fetched user data:", userRecord.toJSON());
})
res.status(200).send({data: userRecord.toJSON()});
return nex();
.catch(function (error) {
console.log("Error fetching user data:", error);
res.status(117);
return nex();
});
});
now I want to access userRecord.toJSON() inside my controller:
$http.post('/.firebase-user', {uid: firebase.auth().currentUser.uid})
.then(function(response) {
console.log($scope.data, response.userRecord);
});
But it is not printing the userRecord.toJSON(), instead I get true undefined in the console.
Please help me to fetch the info back inside my app. thanks
It looks like there are a few issues with your (Express) app request handler:
In your Angular code, you make a request to the /.fb endpoint but in your server code you are listener on the /.firebase-user endpoint. I assume you want these to both be the same.
Your server code never actually sends a response to the Angular code. I'm surprised your then() completion handler ever actually completes. You should need to explicitly send a response with something like res.status(200).send(userRecord.toJSON()) in the success case and res.status(400).send({ error: error }) in the error case.
You should add a catch() to your Angular code to ensure you are catching any errors or failed requests being made by the server code.

Unable to get a JSON response from my express router using node-Fetch module

So I'm making a post request to my Express search router where I'm using the node-fetch module to call a remote api:
var fetch = require('node-fetch');
router.route('/search')
//Performs Job Search
.post(function(req, res){
var area = req.body.area;
fetch('https://api.indeed.com/ads/apisearch?publisher=*********&l=' + area)
.then(function(res) {
return res.json();
}).then(function(json) {
console.log(json);
});
})
I'm using angular 1 on the client side to call the router and parse the returned json:
$scope.search = function(){
$http.post('/api/search', $scope.newSearch).success(function(data){
if(data.state == 'success'){
//perform JSON parsing here
}
else{
$scope.error_message = data.message;
}
});
}
I'm just starting out with the MEAN stack and only have a vague idea of how promises work. So my issue is that my angular search function is not getting the JSON string I want to return from my remote API call. But rather the data parameter is getting set to my page html. Eventually the breakpoints I've set in the .then() clauses are hit and my json is returned. So my question is how can I use Anguular to get the JSON values when they are finally returned????
Can you try something like this?
router.route('/search')
//Performs Job Search
.post(function(req, res){
var area = req.body.area;
fetch('https://api.indeed.com/ads/apisearch?publisher=*********&l=' + area)
.then(function(result) {
res.json(result);
//or possibly res.send(result), depending on what indeed responds with
})
})
Turns out I had forgotten that I had middleware in place where if the user was not authenticated when performing the search they were redirected to the login page. So I was getting a bunch of html returned for this login page, rather then my json. What still confuses me is why my breakpoints in search function were ever hit if I was being redirected before ever reaching this function.

Retrieving data using $http.post

Hi I want to get data from my json file using post method(which is working 5n with get method)
'use strict';
angular.module('myapp').controller('lastWeekWinners',function($http){
var vm= this;
$http.post('http://localhost:9000/json/sample.json').then(function(data){
vm.winnerData=data.data.data;
},function(error){
console.log(error);
});
});
the about code is give error
which means can't we use post method to get the data
This is how u can use the post method in your controller:
'use strict';
angular.module('myapp').controller('lastWeekWinners', controller){
function controller($scope,fetch){
var vm= this;
vm.show = show;
}
function show() {
return fetch.show()
.then(function successCallback(data){
vm.winnerData = data;
}
}, function errorCallback (response) {
console.log(response.statusText);
});
}
});
and in your service :
angular
.module('service',[])
.service('fetch', Service);
function Service($http) {
var fetch = {
show : show
}
return fetch;
function show() {
return $http.get('http://localhost:9000/json/sample.json')
.then(getShowComplete)
.catch(getShowFailed);
function getShowComplete(response){
return response.data;
}
function getShowFailed(error){
console.log("Error:" + error);
}
}
First of all, the difference between GET/POST:
GET is used for getting data, POST is used for saving (and sometimes updating) data. So if you just want to get the json, use GET.
Regarding the specific problem you have here, if you look carefully, you get a 404 code. that means the route was not found. (You can read more about HTTP status code here: http://www.restapitutorial.com/httpstatuscodes.html)
Not sure what server you're using but usually, you're not only defining a route but also the verb of the route (GET/POST/PUT/DELETE), so if you have a route defined like:
GET /users/
This will only work for GET requests, if you try to post for the same route you'll get 404. You have to define the same route for the POST verb.
You can read more about http verbs here: http://www.restapitutorial.com/lessons/httpmethods.html
To do $http.post you need a back end API(PHP,Node Js etc),that system catch your desired post data and save into the db or JSON(Read/Write Method).
Static JSON data just read only possible not write.
Or used Browser $window.localStorage to save data.

How to route a specific JSP using AngularJS

I am new to AngularJS. I have the code below and need to redirect it to a different JSP if the service is success
$scope.User = $resource('anc/validUser', data)
.get().$promise.then(
function(response){
console.log('success');
$location.path('/home');
}, function() {
console.log('error');
});
I was using $location and I am not sure if that is a valid one. Can someone guide me to understand how to route to a different JSP. I have a login.jsp and after the authentication validation through a REST service, I need to take the user to home.jsp

Resources