AngularJS injection Factory into Controller strange error - javascript

I've read numerous posts on stackoverflow and non of them really helped.
I have strange situation where I need to inject Factory into Controller and
everything seems regular but It doesnt work.
Here is factory:
zimmerApp.factory('AuthService', [function ($http, $sanitize) {
var sanitizeCredentials = function (credentials) {
return {
email: $sanitize(credentials.email),
password: $sanitize(credentials.password),
csrf_token: credentials.csrf_token
};
};
return {
login: function (credentials) {
var login = $http.post("/login", sanitizeCredentials(credentials));
login.success(cacheSession);
login.error(loginError);
return login;
}
};
}]);
and controller in which I need to use AuthService is :
zimmerApp.controller('loginCtrl', ['$scope', 'AuthService',
function ($scope, $location, AuthService) {
var xhReq = new XMLHttpRequest();
xhReq.open("GET", "http://" + window.location.hostname + ":8000/auth/token", false);
xhReq.send(null);
$scope.error = false
$scope.credentials = {
username: '',
password: '',
csrf_token: xhReq.responseText
};
$scope.login = function (credentials) {
AuthService.login($scope.credentials)
.success(function () {
$location.path('/');
})
.error(function (err) {
console.log('error')
});
}
}]);
The error I'm getting is
TypeError: Cannot read property 'login' of undefined
so it seems like it doesn't recognize AuthService factory for some reason.
Does anyone know what could I do to fix this, I really don't have an idea anymore.

The params being injected does not match the params in your function.
Change:
zimmerApp.controller('loginCtrl',
['$scope', 'AuthService',
function ($scope, $location, AuthService) {
To:
zimmerApp.controller('loginCtrl',
['$scope', $location, 'AuthService',
function ($scope, $location, AuthService) {
I prefer not using the inject array though:
zimmerApp.controller('loginCtrl',
function ($scope, $location, AuthService) {

Related

.run starts before $http callback. Angular ui-router

I'm using ui-router 1.0.0.X with it's transitions new standart.
My code:
Service for login, save data in storage, determine if it exist and clear
app.factory('AuthService', ['$http', '$cookies', '$rootScope',
function ($http, $cookies, $rootScope) {
var service = {};
// Authenticates throug a rest service
service.authenticate = function (email, password, callback) {
$http.post('endPoints/login.php', {
email: email,
password: password
})
.then(function (response) {
callback(response);
});
};
// Creates a cookie and set the Authorization header
service.setCredentials = function (response) {
$rootScope.globals = response;
$http.defaults.headers.common['Authorization'] = 'Bearer ' + response;
$cookies.put('globals', $rootScope.globals);
};
// Checks if it's authenticated
service.isAuthenticated = function () {
console.log("If TRUE callback not worked yet!!",$cookies.get('globals') === undefined);
return !($cookies.get('globals') === undefined);
};
// Clear credentials when logout
service.clearCredentials = function () {
$rootScope.globals = undefined;
$cookies.remove('globals');
console.log("CLEAN coockies globals",$cookies.get('globals'));
$http.defaults.headers.common.Authorization = 'Bearer ';
};
return service;
}
]);
Configuration and run. There we have transitions methods to work:
angular.module('myApp',
['ui.router',
'ngCookies'
])
.config(['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/resumen');
$stateProvider
.state("dashboard", {
url: "/dashboard",
templateUrl: "partials/dashboard.html",
controller: "dashCtrl",
data: {
authRequired: true
}
})
.state("login", {
url: "/login",
templateUrl: "partials/login.html",
controller: "loginController"
})
}])
.run(['$rootScope', '$transitions', '$state', '$cookies', '$http', 'AuthService',
function ($rootScope, $transitions, $state, $cookies, $http, AuthService) {
// keep user logged in after page refresh
$rootScope.globals = $cookies.get('globals') || {};
$http.defaults.headers.common['Authorization'] = 'Bearer ' + $rootScope.globals;
$transitions.onStart({
to: function (state) {
return state.data != null && state.data.authRequired === true;
}
}, function () {
console.log("I'm transition.onStart and i'm alive!!!");
if (!AuthService.isAuthenticated()) {
return $state.target("autorize");
}
});
}]);
In dashboard state i use data to mark the state only accessible if is authenticated.
Then, on the .run I use the transitions to check the autheticated state.
my controller. $scope.logIn binded to ng-click directive:
$scope.logIn = function () {
AuthService.authenticate($scope.loginInfo.email, $scope.loginInfo.password, function (callback) {
console.log("CALLBACK!",callback); //-> callback from server. Always true
AuthService.setCredentials(callback);
});
}
All this works as expected, but on first ng-click i recieve those:
so, .run method with transitions runs BEFORE ng-click callback from server.
On second ng-click data was already set in previous ng-click server request so everything works FINE!
So, the question is how to avoid those terrible two ng-click calling.
documentation for $transition where i took part of code:
http://angular-ui.github.io/ui-router/1.0.0-alpha.1/interfaces/transition.ihookregistry.html
related post: angular ui-router login authentication

AngularJS: How to fetch data of specific id from JSON file

In my controller class I fetch the id of specific user from URL and then send it to service OrderService Now in the service I want to retrieve the data of this id from JSON file , How can I achieve this ?
OrderCtrl
'use strict';
angular.module('Orders').controller('OrderCtrl', ['$scope', '$state', "SettingService", "OrderService","$stateParams", function($scope, $state, SettingService, OrderService,$stateParams) {
var OrderId = $stateParams.orderId;
$scope.orders = [];
OrderService.getOrderDetails(OrderId).then(function(response){
$scope.orders = response.data.data;
}, function(error){
})
}]);
OrderService.js
angular.module('Orders')
.service('OrderService', ['$http', '$state', '$resource', '$q', 'SettingService', '$localStorage', "MessageService",
function($http, $state, $resource, $q, SettingService, $localStorage, MessageService) {
var service = {
getOrderDetails : function(OrderId){
Here I want to retrieve data from JSON file
});
}
}
return service;
}]);
Try to use something like this
'use strict';
angular.module('Orders').controller('OrderCtrl', ['$scope', '$state', "SettingService", "OrderService", "$stateParams", function ($scope, $state, SettingService, OrderService, $stateParams) {
var OrderId = $stateParams.orderId;
$scope.orders = [];
OrderService.getOrderDetails(OrderId).then(function (response) {
$scope.orders = response.data.data;
});
}]);
// I act a repository for the remote json collection.
angular.module('Orders').service("OrderService", ['$http', '$state', '$resource', '$q', 'SettingService', '$localStorage', "MessageService",
function ($http, $state, $resource, $q, SettingService, $localStorage, MessageService, handleResponse) {
// Return public API.
return ({
getOrderDetails: getOrderDetails
});
// I get all the remote collection.
function getOrderDetails(OrderId) {
var request = $http({
method: "get",
url: '/ajax/order/details', // for example
params: {'id': OrderId}
});
return (request.then(handleResponse.success, handleResponse.error));
}
}]);
angular.module('Orders').service('handleResponse', function ($http, $q, $location) {
return {
error: function (response) {
// The API response from the server should be returned in a
// nomralized format. However, if the request was not handled by the
// server (or what not handles properly - ex. server error), then we
// may have to normalize it on our end, as best we can.
if (!angular.isObject(response.data) || !response.data.message) {
// Something was wrong, will try to reload
return ($q.reject("An unknown error occurred."));
}
// Otherwise, use expected error message.
return ($q.reject(response.data.message));
},
success: function (response) {
return (response.data);
}
};
});

Service undefined when injected into controller

I have a controller that I have injected a factory into but it comes back as undefined when I call a method on that factory. Not sure what I am doing wrong here. Any help would be appreciated.
Factory:
(function(){
'use strict';
// Declare factory and add it 'HomeAutomation' namespace.
angular.module('HomeAutomation').factory('AuthenticationService', ['$http','$localStorage', '$window', function($http, $localStorage, $window){
var service = {};
service.login = Login;
service.logout = Logout;
service.parseJWT = parseJWT;
service.loginStatus = loginStatus;
return service;
function Login(email, password, callback){
$http.post('api/user/login', {email: email, password: password})
.success(function(res){
// Login successful if there is a token in the response.
if(res.token){
// store username and token in local storage to keep user logged in between page refreshes
$localStorage.currentUser = { email: email, token: res.token };
// add jwt token to auth header for all requests made by the $http service
$http.defaults.headers.common.Authorization = 'Bearer ' + res.token;
callback(true);
}else{
callback(res);
}
}).error(function(err){
console.log(err);
});
}
function Logout(){
$localStorage.currrntUser
}
function parseJWT(token){
var base64URL, base64;
base64URL = token.split('.')[1];
base64 = base64URL.replace('-', '+').replace('_', '/');
console.log(JSON.parse($window.atob(base64)));
}
function loginStatus(){
if($localStorage.currentUser){
return true;
}else{
return false;
}
}
}]);}());
Controller:
(function(){
angular.module('HomeAutomation')
.controller('loginController', ['$scope', '$location', 'AuthenticationService', function($scope, $location, $localStorage, AuthenticationService){
$scope.isLoggedIn = AuthenticationService.logout();
$scope.logUserIn = function(){
AuthenticationService.login($scope.login.email, $scope.login.password, function(result){
if(result === true){
$location.path('/');
}else{
console.log(result);
}
});
};
$scope.logUserOut = function(){
AuthenticationService.logOut();
}
}]);}());
This is the line that is causing the err:
$scope.isLoggedIn = AuthenticationService.logout();
Apparently "AuthenticationService" is undefined. Not sure why.
Thanks in advance.
You messed up with depedency sequence, you need to remove $localStorage from controller factory function since $localStorage isn't use anywhere in controller & haven't injected in DI array.
.controller('loginController', ['$scope', '$location', 'AuthenticationService',
function($scope, $location, AuthenticationService){
//^^^^^^^^^^removed $localStorage dependency from here
NOTE: Always make sure when you inject any dependency in DI array, they should used in same sequence in controller function
The injection is not good :
.controller('loginController', ['$scope', '$location', 'AuthenticationService', function($scope, $location, $localStorage, AuthenticationService){
Try with this :
.controller('loginController', ['$scope', '$location', '$localStorage', 'AuthenticationService', function($scope, $location, $localStorage, AuthenticationService){
I don't know which builder you use, but for example with Gulp, you can use gulp-ng-annotate that will do the job for you so that you can only write :
.controller('loginController', function($scope, $location, $localStorage, AuthenticationService){
without the array. The ng-annotate will take care of the rest.

Issue with Url redirect on $location in Angularjs - Cannot read property 'path' of undefined

I'm new to AngularJS and I'm trying to run this AngularJS that should modify the URL without reloading the page when I click on my submit button but in console I get TypeError: Cannot read property 'path' of undefined.
Can't really see where I missed $location injection.
What could be the problem?
var app = angular.module("SearchAPP", ['ngRoute']);
app.run(['$route', '$rootScope', '$location',
function($route, $rootScope, $location) {
var original = $location.path;
$location.path = function(path, reload) {
if (reload === false) {
var lastRoute = $route.current;
var un = $rootScope.$on('$locationChangeSuccess', function() {
$route.current = lastRoute;
un();
});
}
return original.apply($location, [path]);
};
}
]);
app.controller('GetController', ['$http', '$scope', '$location',
function($http, $scope, $rootScope, $location) {
$scope.click = function() {
var response = $http({
url: 'http://localhost:4567/search',
method: "GET",
params: {
keyword: $scope.searchKeyword
}
});
response.success(function(data, status, headers, config) {
$scope.searchResults1 = data;
// $http.defaults.useXDomain = true;
$location.path('/' + $scope.searchKeyword, false);
});
response.error(function(data, status, headers, config) {
alert("Error.");
});
};
}
]);
Wrong dependency sequence in DI array, $rootScope is missing from DI array 3rd parameter. Make sure injected dependency should be using in same sequence in controller function
// VVVVVVVV $rootscope was missing
app.controller('GetController', ['$http', '$scope', '$rootScope','$location',
function($http, $scope, $rootScope, $location) {

How to access $scope variable declared in service callback function in ng-init or ng-checked

I have service.js in which authentication takes place.On success service callback function is executed from controller.js
service.js:
'use strict';
angular.module('Authentication')
.factory('AuthenticationService', ['$http', '$cookieStore', '$rootScope','$timeout', '$location', '$window',
function ($http, $cookieStore, $rootScope, $timeout, $location, $window) {
var service = {};
service.Login = function (username, password, callback) {
$http.post('..json', {
headers: {
username: username,
password: password
}
})
.success(function (data, status, headers, config) {
$timeout(function () {
callback(status);
}, 1000);
});
};
return service;
}])
controller.js:
'use strict';
angular.module('Authentication').controller('LoginController', ['$scope', '$rootScope', '$location', 'AuthenticationService', '$http', '$timeout', '$window',
function ($scope, $rootScope, $location, AuthenticationService, $http, $timeout, $window) {
**$scope.name=true;**
$scope.login = function () {
AuthenticationService.Login($scope.username, $scope.password, function (response) {
if (response === 'Success') {
$http.get('..json').success(data,status,headers,config){
**$scope.value=true;**
})
} else {
alert("Error");
}
});
};
}]);
HTML :
I have 2 checkboxes linked with two $scope variable from controller-$scope.name and $scope.value
<input type="checkbox" ng-checked="name"> abc
<input type="checkbox" ng-checked="value">xyz
Now since both $scope variable is set to true both checkboxes should be initially checked....but the checkbox with $scope.name is checked and $scope.value is unchecked
Any idea about why this happens and how can I make the second check box also initially checked based on the $scope.value
here is a working version almost exactly same as your original code, the only thing i see might be wrong is if (response === 'Success'), because in my example code, the status in .success(data,status,headers,config) is a number not string like "Success", also check this official document here.

Categories