I am working on AngularJS 1.5 project where I have to clear some settings before logout()
Working code (which does not clear settings)
this.logout = userSession.logout
userSession is a service which has logout
Modified code (which clears the settings but does not logout)
this.logout = () => {
mySettings.clear()
userSession.logout
}
Html Code:
<a href="" ng-click="$ctrl.logout()">
<span class="icon-logout"</span>
</a>
You forgot the parentheses when calling userSession.logout.
Should be:
this.logout = () => {
mySettings.clear()
userSession.logout(); // added parentheses
}
Related
I'm trying to logout using this method:
In render I have a div like this:
<div>
<a href="#" onClick={this.logout()}>LOGOUT</a>
</div>
and the logout function:
logout() {
// localStorage.clear();
location.href = 'localhost:3000';
}
At localhost:3000 I have the login page.
Put when I press logout, nothing happends. What can I do?
Thank you
this solved my problem
logout() {
localStorage.clear();
window.location.href = '/';
}
Give to us the Minimal Example to be tested.
You already checked if your function is being called? Try to put some console.log inside logout(), it smells Binding to methods of React class issue.
Try to insert http:// inside location.href, like this: location.href = 'http://localhost:3000';
This is login button. So if it is present, it should login. If not, should go on code.
<button class="md-button ng-scope
md-ink-ripple layout-align-xs-start-start"
type="button" ng-transclude="" data-menu-item="login" ng-click="vm.login()"
ng-if="!vm.isAuthenticated()" layout-align-xs="start start"
aria-label="person_outline global.menu.account.login">
<md-icon class="ng-scope material-icons">person_outline</md-icon>
<label translate="" class="ng-scope">Giriş</label>
<div class="md-ripple-container"></div>
</button>
I tried
describe('Product dashboard module', function () {
console.log('Product Dashboard Test starting');
var dashboardPageObject = new DashboardPageObject();
beforeEach(function () {
var EC = protractor.ExpectedConditions;
browser.wait(EC.visibilityOf(element(by.css('ng-click="vm.login()"')).then(function () {
console.log('-Loging in');
//here will be login jobs
})
})
but
Failed: element(...).then is not a function
I change to this
var EC = protractor.ExpectedConditions;
browser.wait(EC.visibilityOf(element.all(by.cssContainingText('ng-click="vm.login()"'))
.then(function () {
error is:
Failed: Cannot read property 'bind' of undefined
I tried lots of things.
The error Failed: Cannot read property 'bind' of undefined is because in your EC.visibilityOf() method you are trying to pass element.all() which is an array. Buy EC will accept only ElementFinder and not ElementArrayFinder.
So if you want to perform certain operation only if the element available have a look at below example.
beforEach(function(){
element(by.css('button.layout-align-xs-start-start')).isPresent().then(function(isElementDisplayed){
if(isElementDisplayed){
//perform login operation;
}
})
})
I couldn't understand your If not, should go on code. in your question. I have tried the below code, edit the else part as per your wish
var loginBtn = elemeent(by.buttonText('Login'));
loginBtn.isDisplayed().then(function (bool) {
if (bool) {
loginBtn.click();
} else {
// your logic goes here
}
});
You have a typo, you are missing 2 closing parenthesis on your browser.wait() call... Also your locator is incorrect, when accessing an attribute other than class, you need to use square brackets.
browser.wait(EC.visibilityOf(element(by.css('[ng-click="vm.login()"]'))))
And since Protractor is asynchronous you don't need a .then() after browser.wait()
I created this alert service:
class AlertService {
msg = null;
constructor() { }
confirm = (msg) => {
var self = this
this.msg = msg;
}
cancel = () => {
this.msg = null;
return false;
}
okay = () => {
this.msg = null;
return true;
}
}
What I would like to do it to have in my controller something like this:
alertService.Confirm("Confirm or cancel")
.then(function () {
ts.doDelete(es.exam.examId)
}
Here's my html. Note that al is already wired to the AlertService.
<div id="alert"
ng-show="al.msg">
<div>{{ al.msg }}</div>
<button ng-click="al.okay()">
Okay
</button>
<button ng-click="al.cancel()">
Cancel
</button>
</div>
My problem with this is I know how to call the confirm() and pass it the message but how can I make the alert service sit waiting until the user presses the Cancel or Okay buttons in a similar way to when I use the javascript confirm to make a confirmation box appear on my screen?
You have to return promise from Confirm method. And resolve it or reject on yes/no handlers.
http://andyshora.com/promises-angularjs-explained-as-cartoon.html
Here you can find similar solutions:
http://www.bennadel.com/blog/2632-creating-asynchronous-alerts-prompts-and-confirms-in-angularjs.htm
https://github.com/likeastore/ngDialog
I am currently developing a new project that uses AngularJS and Twitter Bootstrap 3.0 for styling.
The project also uses ASP.NET MVC WebAPI to provide a RESTful API with role based security as well as generating bearer and refresh tokens using Owin and OAuth.
One of the key aspects of the project is that it must be able to refresh the navbar menu by adding and/or removing menu options depending on the roles/permissions assigned to individual users. If a user is currently logged into the application and a system administrator decides to add or removed roles for the logged in user I would like AngularJS to automatically reload the navbar, which will magically show or hide options based on the roles the user has.
I do not know very much about AngularJS at this point and would like to know if this is possible? I have heard something called $scope.apply() and that it could be used for this, but as an inexperienced AngularJS user I am not sure how this could be used.
This is a portion of my view that displays the menu bar, and as you can see I am using functions to show/hide menu options. I'd like these functions to be re-evaluated again if their values change once a new refresh token has been generated by a WebAPI call.
<li data-ng-if="isAuthenticated()" class="dropdown">
Invoice <b class="caret"></b>
<ul class="dropdown-menu">
<li><a data-ng-if="isUserInInvoiceRole()" data-ui-sref="addInvoice">Add Invoice</a></li>
<li data-ng-if="isUserInInvoiceRole()" class="divider"></li>
<li><a data-ng-if="isUserInCreditNoteRole()" data-ui-sref="addCreditNote">Issue Credit Note</a></li>
<li data-ng-if="isUserInCreditNoteRole()" class="divider"></li>
<li><a data-ui-sref="showDaybook">Daybook</a></li>
<li class="divider"></li>
<li><a data-ui-sref="showCustomerLedger">Customer Ledger</a></li>
</ul>
</li>
At present the only way I can force the navbar to be refreshed is by doing a page refresh via F5, which proves that the role based system works, but I'd like it to work automatically by reloading the navbar.
Controller
'use strict';
appModule.controller('indexController', ['$scope', '$state', 'authService',
function ($scope, $state, authService) {
$scope.isAuthenticated = function () {
return authService.isAuthenticated();
};
$scope.isUserInCreditNoteRole = function () {
return authService.isAuthenticated() && authService.isUserInCreditNoteRole();
};
$scope.isUserInInvoiceRole = function () {
return authService.isAuthenticated() && authService.isUserInInvoiceRole();
};
$scope.isUserInOrderRole = function () {
return authService.isAuthenticated() && authService.isUserInOrderRole();
};
$scope.isUserInAdminRole = function () {
return authService.isAuthenticated() && authService.isInAdminRole();
};
}]);
Auth service
Here is the auth service with the relevant code. Bear in mind that the [roles.xxx] are just constants.
'use strict';
appModule.factory('authService', ['$http', 'roles',
function ($http, roles) {
var authServiceFactory = {};
var authentication = {
isAuth: false,
roles: "Anon"
};
var checkRoles = function (access) {
var result = false;
for (var a in access) {
console.log(access[a]);
for (var b in access[a]) {
if (authentication.roles.indexOf(access[a][b]) >= 0) {
result = true;
break;
}
}
if (result)
break;
}
console.log('result ' + result);
return result;
};
var isUserInInvoiceRole = function () {
return checkRoles([roles.invoice]);
};
var isUserInOrderRole = function () {
return checkRoles([roles.order]);
};
var isUserInCreditNoteRole = function () {
return checkRoles([roles.creditNote]);
};
var isInAdminRole = function () {
return checkRoles([roles.admin]);
};
var isAuthenticated = function () {
return authentication.isAuth;
}
authServiceFactory.isAuthenticated = isAuthenticated;
authServiceFactory.isUserInCreditNoteRole = isUserInCreditNoteRole;
authServiceFactory.isUserInInvoiceRole = isUserInInvoiceRole;
authServiceFactory.isUserInOrderRole = isUserInOrderRole;
authServiceFactory.isInAdminRole = isInAdminRole;
return authServiceFactory;
}]);
I have managed to resolve this myself after understanding how AngularJS watches updates to a controllers' scope.
I simply repopulated the authentication object in the authentication service, after a new refresh token had been retrieved and the nav bar updated instantly.
I have an AngularJS app, and I want to implement G+ sign-in. I've gone through their samples, and they work as standalone apps.
https://developers.google.com/+/web/signin/
In my Angular app, I am able to display the G+ sign-in button. But I'm stuck on the callback. Do I put the callback function in my controller js file?
If so, and given this controller:
app.controller('myController', function ($scope) {
function signinCallback(authResult) {
On my data-callback, how do I name it so that it goes to signinCallback inside myController?
<span id="signinButton">
<span
class="g-signin"
data-callback="signinCallback"
data-clientid="123456789.apps.googleusercontent.com"
data-cookiepolicy="single_host_origin"
data-requestvisibleactions="http://schemas.google.com/AddActivity"
data-scope="https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.profile.emails.read"
</span>
</span>
The Google+ PhotoHunt sample app demonstrates an AngularJS integration with Google+. The sample is available in Ruby, Java, Python, and C#/.NET for web.
Of note should be the following code in the AngularJS front-end:
Markup to render the button in:
<span id="signin" ng-show="immediateFailed">
<span id="myGsignin"></span>
</span>
JavaScript to glue the markup to code:
$scope.signIn = function(authResult) {
$scope.$apply(function() {
$scope.processAuth(authResult);
});
}
$scope.processAuth = function(authResult) {
$scope.immediateFailed = true;
if ($scope.isSignedIn) {
return 0;
}
if (authResult['access_token']) {
$scope.immediateFailed = false;
// Successfully authorized, create session
PhotoHuntApi.signIn(authResult).then(function(response) {
$scope.signedIn(response.data);
});
} else if (authResult['error']) {
if (authResult['error'] == 'immediate_failed') {
$scope.immediateFailed = true;
} else {
console.log('Error:' + authResult['error']);
}
}
}
$scope.renderSignIn = function() {
gapi.signin.render('myGsignin', {
'callback': $scope.signIn,
'clientid': Conf.clientId,
'requestvisibleactions': Conf.requestvisibleactions,
'scope': Conf.scopes,
'apppackagename': 'your.photohunt.android.package.name',
'theme': 'dark',
'cookiepolicy': Conf.cookiepolicy,
'accesstype': 'offline'
});
}
Within processAuth, you should see an access token and can update your UI to reflect this. You can also see the full controller's JavaScript code on GitHub.
I am not sure if this works, but I would try it like this:
module.factory("GPlusAuthService", function ($q, $window) {
var signIn;
signIn = function () {
var defered = $q.defer();
$window.signinCallback = function (response) {
$window.signinCallback = undefined;
defered.resolve(response);
};
gapi.auth.signIn({
clientid: "123456789.apps.googleusercontent.com"
cookiepolicy: "single_host_origin"
requestvisibleactions: "http://schemas.google.com/AddActivity"
scope: "https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.profile.emails.read",
callback: "signinCallback"
})
return defered.promise;
};
return {
signIn: signIn;
}
});
module.controller('myController', function ($scope, GPlusAuthService) {
$scope.signIn = function() {
GPlusAuthService.signIn().then(function(response) {
});
}
});
<span id="signinButton" ng-controller="myController">
<span class="g-signin" ng-click="signIn()"></span>
</span>
Function that is going to be called after user agrees to sign in is specified in data-callback, this function needs to be globally accessible, that is bound to window object.
Accessing global object from controller is an anti-pattern, as a middle ground you can use $window provided by Angular, which you can mock in your tests