How to route a specific JSP using AngularJS - 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

Related

Angular JS POST Submission Failure

I'm new to angular JS. I've followed an online tutorial and created a simple login form on the frontend, and linked it to the backend. Or at least I've tried. The backend is a nodejs/express server, which has a route for handling the login attempts from the frontend. It will be checking to see if the username and password used on the form are from an existing user account, or not.
The problem is that for some reason, the http POST call from the angular controller, always results in a ERR_CONNECTION_TIMED_OUT response in the browser console.
The thing is, though if I interface with the api endpoint using curl, it works just fine and the server does exactly what it's supposed to do. Just for some reason the angular frontend form cannot connect to the backend. Here's the angular controller code:
app.controller('loginCtrl, function($scope, $location, $http){
$scope.login = function(){
var parameter = JSON.stringify({ username: $scope.username, password: $scope.password });
$http({
url: 'https://localhost:8443/api/login'
method: 'POST',
data: parameter
}).then(function(response){
console.log('success: ' + JSON.stringify(response));
},
function(response){
console.log('failed: ' + JSON.stringify(response));
});
}
});
The nodejs backend server is serving content over HTTPS. This controller function (login) is being hit, and the POST is being made, but it simply times out. And again, manually interfacing with these api endpoints works as expected when using curl or wget.
Any insight into the issue or what I'm doing wrong?

How to go to the url return by a restful service as response

I am calling a java restful service in angularjs
$http
.post($scope.url,datatest)
.success(function(data) {
console.log('success');
// console.log(data);
$scope.responseURL=data;
console.log($scope.responseURL);
})
.error(function(data) {
console.log('error');
});
Here the data is containing a url and I want to go to that url after success of service call.
Actually this is a transaction page where use will hit place Order button and then a service will be called which will return the url of payment getway.
Now I am supposed to redirect to that payment getway url.
Thanks
Edit:
Both the answer bellow are correct but the problem was, I was getting url as 'www.xyz.com/abc....' that's why it was being appended in the current url.
So I just prefixed the response url wiht 'http://' and it worked both way, the same tab and new tab as well.
You can use Angular $window:
$window.location.href = $scope.responseURL;
Inject $window object in your controller function.
You can use $location.path(url):
$location.path(data);
Edit: If you want to open it in another tab, you can try:
$window.open(data, '_blank');
Note: Don't forget to inject $location in your controller.

How to best handle errors in ExpressJS POST routes

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);
});
});

refreshing user.is_authenticated with angular and django rest framework

I'm using django rest framework on the backend and angularjs on the frontend. The problem is the login, in angular I do:
function ($scope, $http, User) {
$scope.login = function (user) {
$http.post('/login/', user)
.then(function (response, status) { // success callback
console.log("success");
console.log(response);
}, function(response) { // error callback
console.log("error");
console.log(response);
})
}
}
then in my views.py I do:
def login_view(request):
user = authenticate(username=request.data['username'], password=request.data['password'])
if user is not None:
login(request, user)
return HttpResponse(status=200)
return HttpResponse(status=400)
But in my home template which is the only django template that I use, the rest is pure html since I use ui-router with state view, so the {% if user.is_authenticated %} won't get updated and I have to refresh the page manually. Is there any solution to make the 'if' statement in the template to be trigger without refreshing all the page, or any better solution to make a login system in my website?
Thank you.
You should not use Django's templatescripts in AngularJS.
AngularJS is a SPA. Django's templatescripts does not work well with SPAs.
You need to create your client logic in javascript only.
This can be done by creating a server endpoint that returns true if a given user is authenticated.

redirecting a page with angular routing after successfully calling an api on express server

In a single page application using angular routing, how can I redirect a page after an api call. In my case, I want to redirect the user to the profile page after they have called the login api. So this is what I thought would work but it isn't.
On the client, main.js. I have the angular routing set up
app.config(function($routeProvider){ $routeProvider
//the home page display
.when('/', {
templateUrl: 'main.html',
controller: 'mainController'
})
.when('/login', {
templateUrl: 'login.html',
controller: 'loginController'
})
.when('/signUp', {
templateUrl: 'signUp.html',
controller: 'signUpController'
})
.when('/profile', {
templateUrl: 'profile.html',
//controller: 'mainController'
}); });
and from my controller I call the /login post api
app.controller('authController', function($scope, $http, $rootScope, $location){
$scope.user = {username: '', password: ''};
$scope.error_message = '';
$scope.login = function(){
$http.post('/login', $scope.user).success(function(data){
if(data.state == 'success'){
//set username authenticated property to true after successful log in
//I am only pasting some of my code here, more logic before controller
$rootScope.authenticated = true;
$rootScope.current_user = "james";
$location.path('/profile');
}
else{
$scope.error_message = data.message;
}
});
};
});
and here is my login api
router.post('/login', passport.authenticate('local-login', {
successRedirect : '/success', // redirect to the secure profile section
failureRedirect : '/failure', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}));
and when it succeeds, it calls success which sends back the data which should trigger the callback in $http.post and redirect the page through $location.path('/profile');. However, the callback isn't called and my page displays the user information from res.send
//sends successful login state back to angular
router.get('/success', function(req, res){
res.send({state: 'success', user: req.user ? req.user : null});
});
Am I on the right track? I am just following microsoft's tutorial https://www.microsoftvirtualacademy.com/en-us/training-courses/mean-stack-jump-start-8442 but their completed page on github doesn't even work so it doesn't help me debug this problem of mine.
Using successRedirect and failureRedirect in passport will redirect the client to the specified pages, which will prevent your client-side angularJS routing from taking place. The reason you're seeing the user info after logging in is because your client is being redirected to the /success page, rather than actually responding to the original request. The client then fetches the success page with a GET request, and the new GET request is then responded to with the user info.
I would suggest leaving the node.js redirects out when using AngularJS, since you probably want to handle redirection on the client side:
router.post('/login', passport.authenticate('local-login'), function(req, res){
res.send(req.user);
});
The inline function will never execute if the user is not authenticated. Instead, passport will respond directly with a 401 error status, with a body of "Unauthorized". Therefore the success state is not required. On the client side, you should use the .error() function to deal with 401 errors, rather than checking your state variable:
$http.post('/login', $scope.user).success(function(user){
$rootScope.authenticated = true;
$rootScope.current_user = "james";
$location.path('/profile');
})
.error(function(err){
$scope.error_message = err;
});
If you want to pass back a more specific reason as to why the request was unauthorized (which is not always a good idea), you can use flash messages, and issue another GET request from angular to get a more detailed authorization failure message.
You seem to have a slight impedance mismatch on what the front-end and back-end want to do here. Your AngularJS code expects to make a POST to the API endpoint and get back a 200 (success) along with some JSON data which tells it about the success or failure of the login attempt.
The back-end, thinks it's going to receive a POST and then redirect the caller to a new location. At least that's the way I'm reading it. It's not simply sending back some data with an HTTP response code of 200 or an error code.
I think you want to tweak the back-end code to simply return data to the front-end to get the result you expect.
So far I haven't seen success in making Ajax calls to API redirecting to a page. We have a similar situation where API call may result in redirecting to a error page. We wanted to handle that in the server rather than asking UI (Angular) to do it. But it's just frustrating to see none of the methods of redirect like res.redirect are working.
Our scenario is Angular makes a API call through Ajax and API running on Node.js should redirect to a html page.

Resources