$location error in angularJS - javascript

I have a master controller and I would like to set up the login page to take me to "/tables" path if username=admin and password=admin, however I am getting this error everytime I try to login
TypeError: Cannot read property 'path' of undefined
I added $location in the controller and in the login function but nothing changed keep getting same error. If I take $location out I get this error
ReferenceError: $location is not defined
Not sure what to do there. Any help is appreciated. Here is my code
angular
.module('RDash')
.controller('MasterCtrl', ['$scope', '$cookieStore', MasterCtrl]);
function MasterCtrl($scope, $cookieStore, $location) {
/**
* Sidebar Toggle & Cookie Control
*/
var mobileView = 992;
$scope.getWidth = function() {
return window.innerWidth;
};
$scope.login = function($location) {
if($scope.credentials.username !== "admin" && $scope.credentials.password !== "admin") {
alert("you are not the admin");
}
else{
$location.path('/tables');
}
};
}
login.html:
<div ng-controller="MasterCtrl">
<form >
<div class="jumbotron" class="loginForm">
<div class="form-group" id="loginPageInput">
<label for="exampleInputEmail1">User Name</label>
<input type="text" class="form-control" id="exampleInputEmail1" placeholder="Enter Username" ng-model="credentials.username">
</div>
<div class="form-group" id="loginPageInput">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password" ng-model="credentials.password">
</div>
<div id="loginPageInput">
<button ng-click="login()" type="submit" class="btn btn-primary btn-lg">Submit</button>
</div>
</form>
<div id="loginPageInput">
<div class="wrap">
<button ng-click="register()" class="btn btn-default" id="lefty" >Register</button>
<p ng-click="forgotpass()" id="clear"><a>Forgot my Password</a></p>
</div>
</div>
</div>
</div>

You missed to inject $location in your dependency array of MasterCtrl
Code
angular
.module('RDash')
.controller('MasterCtrl', ['$scope', '$cookieStore', '$location', MasterCtrl]);
//^^^^^^^^
function MasterCtrl($scope, $cookieStore, $location) {
Also you need to remove $scope.login parameter $location which is killing the service $location variable existance which is inject from the controller.
$scope.login = function ()

You are not passing any $location to login function hence it's undefined and shadows outer $location local variable. Correct code should be:
$scope.login = function () {
if ($scope.credentials.username !== "admin" && $scope.credentials.password !== "admin") {
alert("you are not the admin");
} else {
$location.path('/tables');
}
};

Related

TypeError: Cannot read property '' of undefined in controller with ES6

I am stuck with this error and the thing is I am a newby with angularjs and ES6.
I have a controller for login which calls a service that checks if the user is registered on the database.
It seems I have a problem using this.
The message errors I get are these:
TypeError: Cannot read property 'login' of undefined
at ...
my LoginController.js
class LoginController {
constructor($rootScope, $scope, $timeout, $q, SwapSvc, $state) {
this.submit = this.submit.bind(this)
this.$timeout = $timeout
this.SwapSvc = SwapSvc;
this.$state = $state;
this.status = {
loading: false
}
}
submit(username, password) {
this.status.loading = true
return this.SwapSvc
.login(username,password)
.then((data)=>{
console.log(`los datos recibidos son: ${data.nombre} ${data.apellidos} `);
this.status.loading = false
this.$state.go('main')//ir a pantalla ppal
return data;
})
.catch((err)=>{
//tratar error
console.log(`error, no hay respuesta`);
this.status.loading = false
});
}
}
LoginController.$inject = ['$state', 'SwapSvc'];
export default LoginController
Where SwapSvc is the service that checks whether the user is registered or not.
my login.html
<div class="app-container app-login" ng-class="{__loading: vm.status.loading}">
<div class="flex-center">
<div class="app-header"></div>
<div class="app-body">
<!--"spinner"...-->
<div class="loader-container text-center">
<div class="icon">
<div class="sk-folding-cube">
<div class="sk-cube1 sk-cube"></div>
<div class="sk-cube2 sk-cube"></div>
<div class="sk-cube4 sk-cube"></div>
<div class="sk-cube3 sk-cube"></div>
</div>
</div>
<div class="title">Entrando en su Dashboard...</div>
</div>
<div class="app-block">
<div class="app-form">
<div class="form-header">
<div class="app-brand"><span class="highlight">ReHand</span> Dashboard</div>
</div>
<form ng-submit="vm.submit(vm.username, vm.password)">
<div class="input-group">
<span class="input-group-addon">
<i class="fa fa-user" aria-hidden="true"></i></span>
<input type="email" class="form-control" placeholder="Usuario" ng-model="vm.username">
</div>
<div class="input-group">
<span class="input-group-addon">
<i class="fa fa-key" aria-hidden="true"></i></span>
<input type="password" class="form-control" placeholder="Contraseña" ng-model="vm.password">
</div>
<div class="text-center">
<input type="submit" class="btn btn-success btn-submit" value="Login">
</div>
</form>
</div>
</div>
</div>
<div class="app-footer">
</div>
</div>
</div>
and my route is
.state("login", {
url: "/login",
controller: LoginController,
controllerAs: "vm",
templateUrl: 'pages/pages/login.html'
})
Please help, I am completely lost...
Thanks in advance
Your service is undefined because you are not injecting your Dependencies correctly. $inject kind of maps the values in the array to the position in your constructor function. So, $rootscope will actually be $state and $scope is your Service. To fix this, you need to pass all your Dependecies in both the array for $inject and your constructor function.
constructor($rootScope, $scope, $timeout, $q, SwapSvc, $state) { }
LoginController.$inject = [
'$rootScope',
'$scope',
'$timeout',
'$q',
'SwapSvc',
'$state'
];

Different values stored storing a string with localStorage and $localStorage with Angular 1.

In my angular controller, I am trying to save a token when returned from an API end point which is returned as a string. For this example, I've replaced it with the variable testData.
var testData = "testdata"
$localStorage['jwtToken'] = testData
localStorage.setItem('jwtToken',testData)
For the first line, this is what is stored:
{"ngStorage-jwtToken" : ""testdata""}
First the second line:
{"jwtToken" : "testdata"}
I understand why the key is changing but what I don't understand is why there is a double "" around the data string stored in the value of the key by the first line.
Has anyone come across this before? Am I doing anything wrong?
Best efforts to add the code below.
angular.module('app', [
'ngAnimate',
'ngAria',
'ngCookies',
'ngMessages',
'ngResource',
'ngSanitize',
'ngTouch',
'ngStorage',
'ui.router'
]);
app.controller('SigninFormController', ['$scope', '$http', '$state', '$localStorage',
function($scope, $http, $state, $localStorage) {
$scope.user = {};
$scope.authError = null;
$scope.login = function() {
$scope.authError = null;
// Try to login
$http.post('api/auth/login', {
email: $scope.user.email,
password: $scope.user.password
})
.then(function(response) {
if (response.status = 200 && response.data.token) {
var testData = "testdata"
$localStorage['jwtToken'] = testData
localStorage.setItem('jwtToken', testData)
/*
$localStorage['jwtToken'] = response.data.token
localStorage.setItem('jwtToken',response.data.token)
*/
$state.go('app.home');
} else {
$scope.authError.message
}
}, function(err) {
if (err.status == 401) {
$scope.authError = err.data.message
} else {
$scope.authError = 'Server Error';
}
});
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<body ng-controller="">
<div class="container w-xxl w-auto-xs" ng-controller="SigninFormController">
<div class="m-b-lg">
<div class="wrapper text-center">
<strong>Sign in to get in touch</strong>
</div>
<form name="form" class="form-validation">
<div class="text-danger wrapper text-center" ng-show="authError">
{{authError}}
</div>
<div class="list-group list-group-sm">
<div class="list-group-item">
<input type="email" placeholder="Email" class="form-control no-border" ng-model="user.email" required>
</div>
<div class="list-group-item">
<input type="password" placeholder="Password" class="form-control no-border" ng-model="user.password" required>
</div>
</div>
<button type="submit" class="btn btn-lg btn-primary btn-block" ng-click="login()" ng-disabled='form.$invalid'>Log in</button>
<div class="text-center m-t m-b"><a ui-sref="access.forgotpwd">Forgot password?</a></div>
<div class="line line-dashed"></div>
<p class="text-center"><small>Do not have an account?</small></p>
<a ui-sref="access.signup" class="btn btn-lg btn-default btn-block">Create an account</a>
</form>
</div>
<div class="text-center" ng-include="'tpl/blocks/page_footer.html'">
</div>
</div>
</body>
Why the double quotes
I would need to look at the source code, but most likely the reason why they put quotes around the string is so they can use JSON.parse() so and get the correct object/array/string out of the storage without having to try to figure out the types.
Basic idea:
localStorage.setItem('xxx', '"testData"');
var val1 = JSON.parse(localStorage.getItem('xxx'));
localStorage.setItem('yyy', '"testData"');
var val2 = JSON.parse(localStorage.getItem('{"foo" : "bar"}'));
Why do they prepend the key name?
They can loop over the keys and know what localstorage keys are angulars and what ones are something else. They they can populate their object.
var myStorage = {};
Object.keys(localStorage).forEach(function(key){
if (key.indexOf("ngStorage")===0) {
myStorage[key.substr(10)] = JSON.parse(localStorage[key]);
}
});

why is scope undefined in angular

So I am using ionic to build a hybrid app. Just to be clear, this works flawlessly with android!
Here is my login html:
<body ng-app="starter">
<head>
<script src="phonegap.js"></script>
</head>
<ion-header-bar align-title="center" class="bar-positive" ng-controller="BackBtnCtrl">
<button class="button" ng-click="goBack()"><<</button>
<h1 class="title">Push Notifications</h1>
</ion-header-bar>
<ion-content>
<div class="list">
<form style="display: block; margin: 100px">
<label class="item item-input">
<input type="text" ng-model="name" placeholder="Name">
</label>
<label class="item item-input">
<input type="password" ng-model="password" placeholder="Password" style="text-align: center">
</label>
<label class="item item-input">
<input type="email" ng-model="email" placeholder="Email" style="text-align: center">
</label>
<label class="item item-input">
<input type="text" ng-model="company" placeholder="Company Name" style="text-align: center">
</label>
<button class="button button-block button-positive" type="submit" ng-click="doLogin()">Register</button>
</form>
</div>
</ion-content>
</body>
Now in my app.js I declare the controller for the ion-content as:
.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'LoginCtrl'
})
and when I access, for example, $scope.email in the android app, it returns correctly. But when I access $scope.email in the iOS app, I get undefined. Has anyone ever heard of this issue?
controller:
.controller('LoginCtrl', function($scope, $rootScope, $http, $state, $ionicPlatform) {
if(window.localStorage.getItem("loggedIn") == undefined || window.localStorage.getItem("loggedIn") == null) {
// This function only gets called when the register button gets hit. It posts to the server to store the users registration data
$scope.doLogin = function() {
if ($scope.name == undefined || $scope.password == undefined|| $scope.email == undefined|| $scope.company == undefined) {
window.plugins.toast.showWithOptions(
{
message: 'Please Fill in ALL Fields',
duration: 'long',
position: 'middle'
});
alert($scope.email);
alert("returning");
return;
}
alert($scope.email);
According to the official Angular documentation, you should declare the controller like this:
myApp.controller('GreetingController', ['$scope', function($scope) {
$scope.greeting = 'Hola!';
}]);
So, try change your code in the following way:
.controller('LoginCtrl', ['$scope', '$rootScope', '$http', '$state', '$ionicPlatform', function($scope, $rootScope, $http, $state, $ionicPlatform) {
if(window.localStorage.getItem("loggedIn") == undefined || window.localStorage.getItem("loggedIn") == null) {
// This function only gets called when the register button gets hit. It posts to the server to store the users registration data
$scope.doLogin = function() {
if ($scope.name == undefined || $scope.password == undefined|| $scope.email == undefined|| $scope.company == undefined) {
window.plugins.toast.showWithOptions(
{
message: 'Please Fill in ALL Fields',
duration: 'long',
position: 'middle'
});
alert($scope.email);
alert("returning");
return;
}
alert($scope.email);
This might sound absolutely crazy..
First let me thank all the responses. I have learned a lot with how things should be and how I need to fix my code to be 'standard'. Like using . object instead of primitive strings. Thank You.
But I have solved my issue.The thing that was making my fields undefined, was that I had type='email' and if they just entered in something other than an email, it came back undefined. I don't know how, but that fixed it. I changed type='text' and it fixed my issues.

Ionic redirection

After login test, i tried to go to the home page but i have a problem. I used $location.path("/templates/welcome.html");
but it does not work.
My controller in app.js is :
controller('SignInCtrl', function($scope, $state, $http) {
$scope.login = function(user) {
$http.get("http://localhost/app_dev.php/json/login/"+user.username+"/"+user.password)
.then(function(response){
console.log(response.data.status);
if(response.data.status === 200)
{
alert("redirect to main page");
$location.path("/templates/welcome.html");
}else if(response.data.status === 403){
alert("Login or password incorrect");
}else{
alert("User not found");
}
});
};
})
The alert is working but the redirection does not work. In the console i have this error :
ionic.bundle.js:25642 ReferenceError: $location is not defined
at app.js:37
Inject $location into the controller like this
controller('SignInCtrl', function($scope, $state, $http, $location) {
you have not injected $location service in your controller..
I think the probleme is coming from the statProrovider. My state is :
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('signin', {
url: '/sign-in',
templateUrl: 'templates/welcome.html',
controller: 'SignInCtrl'
})
})
In my html page :
<div ng-controller="SignInCtrl">
<form novalidate class="simple-form">
<div class="list list-inset">
<label class="item item-input">
<input type="text" placeholder="Username" ng-model="user.username">
</label>
<label class="item item-input">
<input type="password" placeholder="Password" ng-model="user.password">
</label>
</div>
<button class="button button-block button-calm" ng-click="login(user)">Login</button>
</form>
I just started using Ionic that's why

How to submit a form using angular ui bootstrap's modal and csrf

I would like to submit a form using Angular UI Bootstrap's modal. I'm instantiating the modal like:
AdminUsers.factory('ProjectsService', ['$resource', function($resource) {
return $resource('/api/users?sort=createdAt desc');
}]).controller('AdminUsersCtrl', ['ProjectsService', '$scope', '$http', '$modal', '$log', function(ProjectsService, $scope, $http, $modal, $log, $modalInstance) {
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: '../templates/userModal.html',
controller: function($scope, $modalInstance) {
$scope.user = {};
$scope.ok = function () { $modalInstance.close($scope.user); };
$scope.cancel = function () { $modalInstance.dismiss('cancel'); };
},
resolve: {
items: function () {
return $scope.user;
}
}
});
modalInstance.result.then(function (user) {
$scope.user = user;
$http.post('/api/users/new', $scope.user).success(function() {
$scope.users.unshift($scope.user);
});
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
}
PS: Please note the controller above does have other methods that is not being displayed above.
The code in my userModal.html is:
<div class="modal-header">
<button type="button" class="close" ng-click="cancel()">×</button>
<h6>New customer</h6>
</div>
<div class="modal-body">
<form class="form-horizontal fill-up separate-sections">
<div>
<label>Name</label>
<input type="text" ng-model="user.name" placeholder="Name" />
</div>
<div>
<label>Email</label>
<input type="email" ng-model="user.email" placeholder="Email" />
</div>
<div>
<label>Admin</label>
<select class="form-control" ng-model="user.admin"
ng-options="option as option for option in [true, false]"
ng-init="user.admin=false"></select>
<input type="hidden" name="user.admin" value="{{user.admin}}" />
</div>
<div>
<label>Password</label>
<input type="password" ng-model="user.password" placeholder="Password" />
</div>
<div>
<label>Password confirmation</label>
<input type="password" ng-model="user.confirmation" placeholder="Password confirmation" />
</div>
<div class="divider"><span></span></div>
<div class="divider"><span></span></div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-blue btn-lg" ng-click="ok()">Save</button>
<button class="btn btn-default btn-lg" ng-click="cancel()">Cancel</button>
<input type="hidden" name="_csrf" value=_csrf />
</div>
The problem lies with the hidden input. I need to submit the csrf with form to the server but I don't know how. If this was a jade template I could simply:
input(type="hidden", name="_csrf", value=_csrf)
and Sails/Express would deal with the rest. But because this is a html template used by Angular only, I don't know how to access the _csrf key. I've tried looking into window.document.cookie however it returned undefined.
Can anyone shed some light on this?
Many thanks

Categories