I have made an login page using angularJS, in which I give username and password static, upon submitting the my form it is redirected to a welcome screen, now I want to logout upon clicking logout , to logout from the welcome page and return to login page? how is it possible using angularJS?
here is the code I wrote :
.controller("loginController", function($scope, $location, $rootScope){
$scope.login = function() {
var user = $scope.username;
var password = $scope.password;
var result = $scope.username + $scope.password;
console.log(result);
if (user == "admin" && password == 'admin'){
$rootScope.loggedIn = true;
$location.path('/welcome');
} else {
alert("INVALID CREDENTIALS");
}
}
.controller('welcomeController', function($scope){
$scope.message = "welcome here"
})
Do as told by Sajeetharan in previous answer.
Just clear values of $scope.username and $scope.password in logout function
Write a function to redirect your page to the home page and do this,
.controller('logoutController', function($scope,$location){
$scope.logout = function(){
//Just clear values from scope
$scope.username = '';
$scope.password = '';
$location.path('/home');
}
})
and call it using ng-click
<button ng-click="logout()">
Logout
</button>
By the way, the approach you are using is not very good.
Write a function to redirect your page to the home page and do this,
.controller('logoutController', function($scope,$location){
$scope.logout = function(){
$location.path('/home');
}
})
and call it using ng-click
<button ng-click="logout()">
Logout
</button>
Related
I created an app using JHipster and try to edit the `register.html'. The code where I need help is shows below:
<div class="alert alert-success" ng-show="vm.success" data translate="register.messages.success">
<strong>Registration saved!</strong> Please check your email for confirmation.
</div>
<div class="alert alert-danger" ng-show="vm.error" data-translate="register.messages.error.fail">
<strong>Registration failed!</strong> Please try again later.
</div>
I omitted the rest of the code as they are equal to these two, only with different messages and ng-models . & the register.controller.js :
(function() {
'use strict';
angular
.module('MyApp')
.controller('RegisterController', RegisterController);
RegisterController.$inject = ['$translate', '$timeout', 'Auth', 'LoginService'];
function RegisterController ($translate, $timeout, Auth, LoginService) {
var vm = this;
vm.doNotMatch = null;
vm.error = null;
vm.errorUserExists = null;
vm.login = LoginService.open;
vm.register = register;
vm.registerAccount = {};
vm.success = null;
$timeout(function (){angular.element('#login').focus();});
function register () {
if (vm.registerAccount.password !== vm.confirmPassword) {
vm.doNotMatch = 'ERROR';
} else {
vm.registerAccount.langKey = $translate.use();
vm.doNotMatch = null;
vm.error = null;
vm.errorUserExists = null;
vm.errorEmailExists = null;
Auth.createAccount(vm.registerAccount).then(function () {
vm.success = 'OK';
}).catch(function (response) {
vm.success = null;
if (response.status === 400 && response.data === 'login already in use') {
vm.errorUserExists = 'ERROR';
} else if (response.status === 400 && response.data === 'e-mail address already in use') {
vm.errorEmailExists = 'ERROR';
} else {
vm.error = 'ERROR';
}
});
}
}
}
})();
My question is by default the error handling messages must be hidden, and once the form is valuated, they should be shown based on the condition. But I cannot figure out how to make this work...
Below is the default register.html page:
The generated register.html does not show those messages by default. It looks like you are loading just the HTML file into the browser, but you need to run the app and load the index.html from there to run the Angular code.
Run ./mvnw or ./gradlew and access the frontend at http://localhost:8080
You can also run gulp which will serve your frontend at http://localhost:9000 with live-reloading when you make changes. More info can be found in the Using JHipster in development documentation
The register page looks like the following image when ran correctly:
I am working on a card processing API with ASP.NET , HTML , AngularJS and Stripe.NET. I am pretty new to all of them.
I followed the documentation on the Stripe website for sending the Stripe token to the server (here): https://stripe.com/docs/stripe.js#card-validateCardNumber
It worked! However, instead of JQuery I want to use AngularJS. I want to convert from JQuery to AngularJS this part of the JQuery code:
Stripe.card.createToken({
number: $('.card-number').val(),
cvc: $('.card-cvc').val(),
exp_month: $('.card-expiry-month').val(),
exp_year: $('.card-expiry-year').val(),
address_zip: $('.address_zip').val()
}, stripeResponseHandler);
function stripeResponseHandler(status, response) {
// Grab the form:
var $form = $('#payment-form');
if (response.error) { // Problem!
// Show the errors on the form
$form.find('.payment-errors').text(response.error.message);
$form.find('button').prop('disabled', false); // Re-enable submission
} else { // Token was created!
// Get the token ID:
var token = response.id;
// Insert the token into the form so it gets submitted to the server:
$form.append($('<input type="hidden" name="stripeToken" />').val(token));
// Submit the form:
$form.get(0).submit();
}
}
If someone can help, I will appreciate it a lot. Thanks. :)
I was able to answer my question (a while ago, just finding some time to answer it in here).
Firstly, here are the tips:
Use "angular-payments.js". You can find it here: https://github.com/laurihy/angular-payments
You have to use the html syntax for the card details as in the documentation of the repository.
It is not the same as in the Stripe documentation. I have used AngularJS service so that I can pass my token to my ASP.NET application.
Thirdly, I had problems with the verification token - here is a nice post for how to handle it: http://blog.novanet.no/anti-forgery-tokens-using-mvc-web-api-and-angularjs/
Here is (part of) my (AngularJS) code:
(function () {
var app = angular.module("myApp", ["angularPayments"]);
app.service('Service', function ($http) {
this.AddCard = function (stripeToken, stripeEmail) {
var tokenData = {
"stripeToken": stripeToken,
"stripeEmail": stripeEmail
};
$http.post("http://localhost:48484/payment/card", tokenData).success(function (response) {
window.location = '/cardprocess/confirmation';
})
};
});
app.directive('ncgRequestVerificationToken', ['$http', function ($http) {
return function (scope, element, attrs) {
$http.defaults.headers.common['RequestVerificationToken'] = attrs.ncgRequestVerificationToken || "no request verification token";
};
}]);
app.controller("myCtrl", ['$scope', myCtrl]);
app.controller("buyCtrl", function ($scope, CardService) {
$scope.submit = function () {
$scope.processing = true;
}
$scope.stripeFormSubmit = function (code, result) {
$scope.processing = false;
$scope.hideAlerts();
if (result.error) {
$scope.stripeError = result.error.message;
} else {
//$scope.stripeToken = result.id;
$scope.stripeToken = result.id;
CardService.AddCard($scope.stripeToken, $scope.stripeEmail);
}
};
$scope.hideAlerts = function () {
$scope.stripeError = null;
$scope.stripeToken = null;
};
});
}());
(The html page is quite big so I decided not to put in here. It should be straight forward - I have a form, which calls AngularJS model "stripeFormSubmit".)
Finally, you can see the "CardService", which is talking to my api - the service is initialised at the begining of the paste code.
That is the main idea. I decided not to go in a lot of detail. But I will try to answer questions (if any).
I have the following scenario. Actual Page loading starts, user login is checked for authentication. If access granted, actual page loading completes and user can access the page. If access denied, actual page loading stops and user is redirected to 'access denied' page.
Infact the scenario should be like this. User authentication is checked. if access granted, actual page loading starts and user can access page. If access denied, user is directly directed to 'access denied' page.
can someone tell me how to include promise for this scenario. current code is as follows.
$q.when().then(function () {
return $rootScope.$emit('resetView', false, 'default');
}).then(function (result) {
loadNavBar(); //actual page loading starts here
}, function (error) {
$log.error("Caught an error:", error);
return $q.reject('New error');
});
the below function is loadNavBar() which gets executed. User authentication is done inside of this. Hence page loading starts and then user is checked. I want user to be checked first itself and then load page accordingly depending on his access rights.
var loadNavBar = function () {
//few functions here to display page.
//below code to check user authentication
var serviceURL_CheckUserExists = '/api/Pre/CheckUserExists';
//ajax to check if user exists in database. give/ deny access based on user present in DB and if user is set as blockuser in db.
$.ajax({
type: "GET",
url: serviceURL_CheckUserExists,
}).then(function (response) {
if (response.Results.length == 1 && response.Results[0].BlockUser == false) { //user has access if condition is satisfied.
$rootScope.myLayout.eventHub.emit('getUserName', response.Results[0].User_ID.trim());
$scope.role = "";
var details = response.Results[0];
for (var parameters in details) {
if (details[parameters] == true) {
$scope.role += parameters + ',';
}
}
$scope.role = $scope.role.replace(/.$/, ".");
var firstname = response.Results[0].FirstName;
firstname = firstname.replace(/\s/g, '');
$scope.$apply(function () {
$scope.username = response.Results[0].FirstName + " " + response.Results[0].LastName;
});
}
else { $window.location.href = '../../../BlockUser.html'; } //block access to actual page and redirect to 'access denied' page.
}
}
});
};
i think that the right approach to your problem is to use resolve property in the route, so the user can't navigate to certain pages if he isn't logged in and once he logged in you can inject the user object to the controller
for example to navigate to home page you must be logged in
.when("/home", {
templateUrl: "homeView.html",
controller: "homeController",
resolve: {
user: function(AuthenticationService){
return AuthenticationService.getUser();
}
}
})
app.controller("homeController", function ($scope, user) {
$scope.user = user;
});
https://www.sitepoint.com/implementing-authentication-angular-applications/
Here's a quick example of hiding the content until the user is authenticated to see it. Click the 'authenticate' button to trigger the function that you would run if the user is authenticated by your ajax call. Showing the content can be done with a fuction like:
function userIsAuthenticated(){
document.getElementById('pageContent').style.display = 'block';
}
See JsFiddle for a simple implementation.
Im trying to verify that a user is logged in. Initially I went with $scope.use, $scope.user.uid, $scope.getCurrenUser() as described on Firebase docs but I think I simply have the dependencies wrong.
Code:
myApp.js
https://gist.github.com/sebbe605/2b9ff7d3b798a58a3886
firebase.js
https://gist.github.com/sebbe605/f9e7b9a75590b3938524
If I understand this correctly there is no way for the program to know that I'm referring to a Firebase user. To clarify I want .controller('templateCtrl',function($scope, $firebase) to have the ability to show a certain button if the user is logged in.
--UPDATE 1--
So, i have updated my files and for what i understand this should work. Previous code are as gits above to enhance the cluther.
myApp.js
angular.module('myApp', [
'ngRoute',
'firebase'
])
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/template',
{
templateUrl:'partials/template.html', controller:'templateCtrl'
});
$routeProvider
.when('/login',
{
templateUrl:'partials/login.html', controller:'signupCtrl'
});
$routeProvider
.when('/signup',
{
templateUrl:'partials/signup.html', controller:'signupCtrl'
});
$routeProvider
.when('/user',
{
templateUrl:'partials/user.html', controller:'userCtrl'
});
$routeProvider
.otherwise('/template');
}])
controllers.js
'use strict';
angular.module('myApp').controller('signupCtrl', function($scope, $http, angularFire, angularFireAuth){
$scope.loginBusy = false;
$scope.userData = $scope.userData || {};
var ref = new Firebase('https://boostme.firebaseio.com/');
angularFireAuth.initialize(ref, {scope: $scope, name: 'user'});
/*//////////////LOGIN - LOGOUT - REGISTER////////////////////*/
$scope.loginEmailText = "Email"
$scope.loginPasswordText = "Password"
$scope.login = function() {
$scope.loginMessage = "";
if ((angular.isDefined($scope.loginEmail) && $scope.loginEmail != "") && (angular.isDefined($scope.loginPassword) && $scope.loginPassword != "")) {
$scope.loginBusy = true;
angularFireAuth.login('password', {
email: $scope.loginEmail,
password: $scope.loginPassword
});
} else {
$scope.loginPassword = ""
$scope.loginPasswordText = "Incorrect email or password"
}
};
$scope.logout = function() {
$scope.loginBusy = true;
$scope.loginMessage = "";
$scope.greeting = "";
$scope.disassociateUserData();
$scope.userData = {};
angularFireAuth.logout();
};
$scope.emailText = "Email"
$scope.passwordText = "Password"
$scope.confirmPasswordText = "Confirm Password"
$scope.register = function() {
$scope.loginMessage = "";
if ((angular.isDefined($scope.email) && $scope.email != "") && (angular.isDefined($scope.password0) && $scope.password0 != "" && $scope.password0 == $scope.password1)) {
$scope.loginBusy = true;
angularFireAuth.createUser($scope.email, $scope.password0, function(err, user) {
if (user) {
console.log('New User Registered');
}
$scope.loginBusy = false;
});
} else {
$scope.password0 =""
$scope.password1 =""
$scope.passwordText = "Password Not Matching"
$scope.confirmPasswordText = "Password Not Matching"
}
};
$scope.$on('angularFireAuth:login', function(evt, user) {
$scope.loginBusy = false;
$scope.user = user;
console.log("User is Logged In");
angularFire(ref.child('users/' + $scope.user.id), $scope, 'userData').then(function(disassociate) {
$scope.userData.name = $scope.userData.name || {};
if (!$scope.userData.name.first) {
$scope.greeting = "Hello!";
} else {
$scope.greeting = "Hello, " + $scope.userData.name.first + "!";
}
$scope.disassociateUserData = function() {
disassociate();
};
});
});
$scope.$on('angularFireAuth:logout', function(evt) {
$scope.loginBusy = false;
$scope.user = {};
console.log('User is Logged Out');
});
$scope.$on('angularFireAuth:error', function(evt, err) {
$scope.greeting = "";
$scope.loginBusy = false;
$scope.loginMessage = "";
console.log('Error: ' + err.code);
switch(err.code) {
case 'EMAIL_TAKEN':
$scope.loginMessage = "That email address is already registered!";
break;
case 'INVALID_PASSWORD':
$scope.loginMessage = "Invalid username + password";
}
});
})
Output:
Error: [$injector:unpr] Unknown provider: angularFireProvider <- angularFire
http://errors.angularjs.org/1.3.0-rc.3/$injector/unpr?p0=angularFireProvider%20%3C-%20angularFire
at http://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.3/angular.js:80:12
at http://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.3/angular.js:3938:19
at Object.getService [as get] (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.3/angular.js:4071:39)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.3/angular.js:3943:45
at getService (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.3/angular.js:4071:39)
at invoke (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.3/angular.js:4103:13)
at Object.instantiate (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.3/angular.js:4123:23)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.3/angular.js:7771:28
at link (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.3/angular-route.js:938:26)
at invokeLinkFn (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.3/angular.js:7549:9) <div ng-view="" class="ng-scope">
(anonymous function) angular.js:10683
(anonymous function) angular.js:7858
invokeLinkFn angular.js:7551
nodeLinkFn angular.js:7069
compositeLinkFn angular.js:6441
publicLinkFn angular.js:6320
boundTranscludeFn angular.js:6461
controllersBoundTransclude angular.js:7096
update angular-route.js:896
Scope.$broadcast angular.js:13751
(anonymous function) angular-route.js:579
processQueue angular.js:12234
(anonymous function) angular.js:12250
Scope.$eval angular.js:13436
Scope.$digest angular.js:13248
Scope.$apply angular.js:13540
done angular.js:8884
completeRequest angular.js:9099
xhr.onreadystatechange angular.js:9038
I cant figure out what the problem is. However i think there is something wrong with: but i can't tell. If more information is needed i'm happy to post it.
I initially was taking the same if-then-else approach as you do for handling privileged actions. But it turns out this is not the best approach when using Angular. Instead of having this if-then-else approach, try to reframe the problem to a solution that isolates the privileged code.
show a certain button if the user is logged in
So your original question was about showing an HTML element only when the user if logged in, which is easy with something like this in your controller:
$scope.auth = $firebaseSimpleLogin(new Firebase(FBURL));
This line binds the Firebase login status to the current scope, which makes it available to the view. No if-then-else is needed, since there is always a login status. AngularFire ensure that the view gets notified when that status changes, so all we have to do is ensure that we have the HTML markup to handle both presence and absence of authenticated users:
<div ng-controller="TrenchesCtrl" class='auth'>
<div ng-show="auth.user">
<p>You are logged in as <i class='fa fa-{{auth.user.provider}}'></i> {{auth.user.displayName}}</p>
<button ng-click="auth.$logout()">Logout</button>
</div>
<div ng-hide="auth.user">
<p>Welcome, please log in.</p>
<button ng-click="auth.$login('twitter')">Login with <i class='fa fa-twitter'> Twitter</i></button>
<button ng-click="auth.$login('github')">Login with <i class='fa fa-github'> GitHub</i></button>
</div>
</div>
See how it almost reads like an if-then-else? But then one without me writing code that tries to detect if the user is logged in. It is all declaratively handled by AngularJS and AngularFire.
perform actions only when a user is logged in
When you actually need to perform a privileged action, I've found it easiest to isolate the code like this:
function updateCard(id, update) {
var auth = $firebaseSimpleLogin(new Firebase(FBURL));
auth.$getCurrentUser().then(function(user) {
update.owned_by = user.username;
var sync = $firebase(ref.child('cards').child(id));
sync.$update(update);
});
};
Note that these are (simplified) fragments from my Trenches app (demo), which I wrote to learn more about Angular and AngularFire.
I have two views right now.
login
main
Right now I login and change my path to /main which works fine. When I am not logged in, and try to visit /main my web service returns "Access denied for user anonymous" which I then forward them to / which is my login view. How can I pass something so my LoginController knows they were forwarded from /main to alert them to login first?
LoginController.js
VforumJS.controller('LoginController', function($scope, $location, $routeParams, LoginModel)
{
$scope.email = "";
$scope.password = "";
$scope.fetching = false;
$scope.error = null;
$scope.login = function()
{
$scope.error = null;
$scope.fetching = true;
LoginModel.login($scope.email, $scope.password);
}
$scope.$on('LoginComplete', function(event, args)
{
log('login complete: ' + args.result);
$scope.fetching = false;
if (args.result == "success")
{
$location.path('/main');
}
else
{
$scope.error = args.result;
}
});
});
MainController.js
VforumJS.controller('MainController', function($scope, $location, $routeParams, MainModel)
{
$scope.currentTitle = '-1';
$scope.presentationData = MainModel.getPresentations();
$scope.$on('PresentationsLoaded', function(event, args)
{
log(args.result);
if (args.result != "Access denied for user anonymous")
{
//-- Parse preso data
$scope.presentationData = args.result;
}
else
{
//-- Need to login first, route them back to login screen
$location.path("/");
}
});
});
You can use $location.search() in your MainController to pass query string to the LoginController.
Inside you MainController:
if (args.result != "Access denied for user anonymous")
{
//-- Parse preso data
$scope.presentationData = args.result;
}
else
{
//-- Need to login first, route them back to login screen
$location.search({ redirectFrom: $location.path() });
$location.path("/");
}
And then in your LoginController, shortened for brevity:
VforumJS.controller('LoginController', function($scope, $location, $routeParams, LoginModel)
{
var queryString = $location.search();
$scope.$on('LoginComplete', function(event, args)
{
log('login complete: ' + args.result);
$scope.fetching = false;
if (args.result == "success")
{
if (queryString && queryString.redirectFrom) {
$location.path(queryString.redirectFrom);
} else {
$location.path('/somedefaultlocation');
}
}
else
{
$scope.error = args.result;
}
});
});
Alternatively you can use a shared service, maybe even your LoginModel to set a parameter from MainController to indicate the redirect came from it.
Update
Even better still, use $httpProvider.interceptors to register a response interceptor, and then use the same $location.search() technique described above to redirect to the login screen on authentication failure. This method is ideal as your controllers are then clean of authentication logic.
$location broadcasts $locationChangeStart and $locationChangeSuccess events, and the third param of each is oldUrl.
One solution would be to have a service that subscribes to $locationChangeStart in order to save the current and old urls.
When you hit /, your LoginController can check your service to see if the oldUrl is /main, and then act accordingly.