Cannot read property 'ClearCredentials' of undefined - javascript

I'm new to angularjs an i'm trying to create a login form but i'm getting following error :
Cannot read property 'ClearCredentials' of undefined.
I have used some tutorial stuff. But now i started to create an application from scratch. But i'm stuck with the AuthenticationService.js
This is what i have done
app.js
(function(angular) {
angular.module("app.directives", []);
angular.module("app.AuthenticationService", []);
angular.module("app.controllers", []);
angular.module("app", ['ngRoute','ngResource','routes','app.directives','app.controllers',"app.AuthenticationService"]);
}(angular));
controller.js
//LoginController
(function (angular) {
var LoginController = function($scope,$location,AuthenticationService){
var vm = this;
//todo vm.login = login;
(function initController() {
// reset login status
// calling function from AuthenticationService
AuthenticationService.ClearCredentials();
})();
/* TODO: This has not been tested yet
function login(){
vm.dataLoading = true;
// constructor from AuthenticationService
AuthenticationService.Login(vm.username,vm.password, function(response){
//Check if method respons === success
if (response.success) {
// calling function from AuthenticationService
AuthenticationService.SetCredentials(vm.username, vm.password);
$location.path('/');
} else {
// use function from FlashService
// FlashService.Error(response.message);
// vm.dataLoading =false;
}
});
}*/
}
LoginController.$inject = ['$scope','$location'];
angular.module("app.controllers").controller("LoginController", LoginController);
}(angular));
AuthenticationService.js
(function (angular) {
var AuthenticationService = function($http, $cookieStore, $rootScope, $timeout, UserService) {
var service = {};
service.ClearCredentials = ClearCredentials;
function ClearCredentials() {
$rootScope.globals = {};
$cookieStore.remove('globals');
$http.defaults.headers.common.Authorization = 'Basic ';
}
return service;
}
AuthenticationService.$inject = ['$http', '$cookieStore', '$rootScope', '$timeout', 'UserService'];
angular.module("app.AuthenticationService").factory("AuthenticationService", AuthenticationService);
})(angular);
If you have suggestions for this code please let me also know.

You inject two parameters:
LoginController.$inject = ['$scope','$location'];
But then you refer to the third one. Isn't this a problem?
Check if the inline version would work:
angular.module("app.controllers").controller("LoginController", funtion($scope,$location,AuthenticationService){
...
}
If it does, then there is an issue with Angular injection.

Related

AngularJS - I don't understand why factory is always undefined

I defined a factory that makes a get request but when I inject it in a controller it always throws an undefined error.
This is the factory:
(function() {
'use strict';
var app = angular
.module('myApp');
app.factory('homeFactory', homeFactory);
function homeFactory ($q, $http, $location) {
var data = {};
data.getProducts = getProducts;
function getProducts() {
return $http.get('http://localhost:8000/api/v1/products')
.error(errorMessage);
}
function errorMessage(response) {
console.log('There was an error', response);
}
return data;
}
})();
This is the controller:
(function() {
'use strict';
var app = angular
.module('myApp');
app.controller('homeController', homeController);
homeController.$inject =[homeFactory];
function homeController(homeFactory) {
var home = this;
homeFactory.getProducts()
.success(success);
function success(jsonData, statusCode) {
console.log('The request was successful', statusCode);
console.dir(jsonData);
home.products = jsonData;
}
}
})();
It appears to be ok, but the console throws:
Uncaught ReferenceError: homeFactory is not defined
The problem is in your DI annotation. You should only use strings
homeController.$inject = ['homeFactory'];
See https://docs.angularjs.org/guide/di#-inject-property-annotation
The $inject property is an array of service names to inject.
The controller function supports dependency injection. You don't need to use the $injector directly. Try this:
var app = angular
.module('myApp');
app.controller('homeController', homeController);
function homeController(homeFactory) {
var home = this;
homeFactory.getProducts()
.success(success);
function success(jsonData, statusCode) {
console.log('The request was successful', statusCode);
console.dir(jsonData);
home.products = jsonData;
}
}
The angular runtime will find the homeFactory service, and automatically pass it to your controller function when it's called.
In controller you shall put factory in dependecies
app.controller('homeController', ['homeFactory', '$scope',
function (homeFactory, $scope){
//scope code goes here
}]
);

myfunction() function call from one controller to another in angularjs

i have used Angularjs and i wanna call getcustomer function from one controller to another controller i have so many doing gooogling but i don't have an idea that how to call that
i have write below code which i used
var app = angular.module('Napp', []);
app.controller('GetAlphabetical', function ($scope, $http) {
function getCutomers() {
$scope.loading = true;
$http.get('#Url.Content("~/Home/GetPesrons")').then(function (response) {
//var _data = angular.fromJson(response);
$scope.loading = false;
$scope.Customer = response.data; // please check the request response if list id in data object
}, function (error) {
throw error;
})
}
});
and second controller :
app.controller('MainCtrl', function ($scope, $http) {
getCutomers()
});
Mate, you will have to follow the following steps to resolve your problem. Firstly you have you create a factory
angular
.module('Napp')
.factory('CustomerFactory', ['$http', function ($http) {
var _factory = {};
_factory.getCustomers = function () {
return $http.get('#Url.Content("~/Home/GetPesrons")');
};
return _factory;
}]);
Then you can share data and functions between multiple controllers or services
GetAlphabetical Controller :
angular
.module('Napp')
.controller('GetAlphabetical', ['$scope', 'CustomerFactory', function ($scope, CustomerFactory) {
loadCustomers();
function loadCustomers() {
CustomerFactory.getCustomers().then(function (successResponse) {
$scope.Customer = successResponse.data; // please check the request response if list id in data object
}, function (errorResponse) {
throw error;
})
}
}]);
MainCtrl Controller :
angular
.module('Napp')
.controller('MainCtrl', ['$scope', 'CustomerFactory', function ($scope, CustomerFactory) {
loadCustomers();
function loadCustomers() {
CustomerFactory.getCustomers().then(function (successResponse) {
$scope.Customer = successResponse.data; // please check the request response if list id in data object
}, function (errorResponse) {
throw error;
})
}
}]);
This can be easily done by defining it as a service and injecting it as a dependency.
var app = angular.module('myApp', []);
myApp.service('helloWorldFromService', function() {
this.sayHello = function() {
return "Hello, World!"
};
});
app.controller('MainCtrl', function ($scope, $http, helloWorldFromService) {
app.controller('GetAlphabetical', function ($scope, $http, helloWorldFromService) {
Angular Service
What you want to do is to somehow communicate between two controllers. This can be easily be achieved using $broadcast & $on.
Incase there is a parent child relation between your controllers, use the following.
function firstCtrl($scope){
$scope.$broadcast('someEvent', [1,2,3]);
}
function secondCtrl($scope){
$scope.$on('someEvent', function(event, mass) {console.log(mass)});
}
If there is no parent child relationship between your controller, then inject $rootScope and broadcast using that.
related question - https://stackoverflow.com/a/14502755/1182982

Angular watch factory value

Say i have the following factory:
app.factory("categoryFactory", function (api, $http, $q) {
var selected = null;
var categoryList = [];
return {
getList: function () {
var d = $q.defer();
if(categoryList.length <= 0){
$http.get(api.getUrl('categoryStructure', null))
.success(function (response) {
categoryList = response;
d.resolve(categoryList);
});
}
else
{
d.resolve(categoryList)
}
return d.promise;
},
setSelected: function (category) {
selected = category;
},
getSelected: function () {
return selected;
}
}
});
now i have two controllers using this factory at the same time. Because of this both controllers has to be notified when updated for this i attempted the following:
app.controller('DashboardController', ['$http', '$scope', '$sessionStorage', '$log', 'Session', 'api','categoryFactory', function ($http, $scope, $sessionStorage, $log, Session, api, categoryFactory) {
$scope.selectedCategory = categoryFactory.getSelected();
}]);
While my other controller looks like this:
app.controller('NavController', ['$http', '$scope', '$sessionStorage', '$log', 'Session', 'api', 'FileUploader', 'categoryFactory', function ($http, $scope, $sessionStorage, $log, Session, api, FileUploader, categoryFactory) {
$scope.categories = [];
categoryFactory.getList().then(function (response) {
$scope.categories = response;
});
$scope.selectCategory = function (category) {
categoryFactory.setSelected(category);
}
}]);
how ever when the NavController changed the value it was not changed in the DashboardController
My question is how can i either watch or in another way get notified when the value changes?
You can use an observer pattern, like so:
app.factory("categoryFactory", function (api, $http, $q) {
// the list of callbacks to call when something changes
var observerCallbacks = [];
// ...
function notifyObservers() {
angular.forEach(observerCallbacks, function(callback) {
callback();
});
}
return {
setSelected: function (category) {
selected = category;
// notify the observers after you change the value
notifyObservers();
},
registerObserver: function(callback) {
observerCallbacks.push(callback);
}
}
});
And then in your controllers:
app.controller('NavController', ['$http', '$scope', '$sessionStorage', '$log', 'Session', 'api', 'FileUploader', 'categoryFactory', function ($http, $scope, $sessionStorage, $log, Session, api, FileUploader, categoryFactory) {
// ...
// init
(function() {
categoryFactory.registerObserver(function() {
categoryFactory.getList().then(function (response) {
$scope.categories = response;
});
});
})();
}]);
This way, any time setSelected is called, it calls each callback that you've registered in observerCallbacks. You can register these from any controller since factories are singletons and they will always be in the know.
Edit: just want to add that I may have put the notifyObservers() call in the wrong area (currently in setSelected) and that I may be putting the wrong update call in the controller (currently getList) but the architecture remains the same. In the registerObserver, put whatever you want to do when the values are updated and wherever you make changes that you want observers to know about call notifyObservers()
You could follow dot rule here so that prototypal inheritance will get followed.
Basically you need to have one object inside your service that will have selected variable, And will get rid of getSelected method.
Factory
app.factory("categoryFactory", function(api, $http, $q) {
var categoryFactory = {};
categoryFactory.getList = function() {
var d = $q.defer();
if (categoryList.length <= 0) {
$http.get(api.getUrl('categoryStructure', null))
.success(function(response) {
categoryList = response;
d.resolve(categoryList);
});
} else {
d.resolve(categoryList)
}
return d.promise;
}
categoryFactory.setSelected = function(category) {
categoryFactory.data.selected = category;
}
categoryFactory.data = {
selected: null
}
return categoryFactory;
});
Controller
app.controller('DashboardController', ['$http', '$scope', '$sessionStorage', '$log', 'Session', 'api', 'categoryFactory',
function($http, $scope, $sessionStorage, $log, Session, api, categoryFactory) {
//this will provide you binding without watcher
$scope.selection = categoryFactory.data;
}
]);
And then use {{selection.selected}} on html part will update a value when changes will occur in selection.

Calling a Service function from a Controller in AngularJS

Controller Code
'use strict';
angular.module('MyApp').controller('ArticleContribEmailController', [
'$scope', 'ArticleAppState', 'fbsUserDataService', 'contribEmailService',
function ($scope, ArticleAppState, fbsUserDataService, contribEmailService ) {
this.userChanged = function () {
if (fbsUserDataService.initialized && fbsUserDataService.user && ArticleAppState.page_data) {
// user has authenticated.
contribEmailService.initForm();
}
};
// watch for when user data is available, run userChanged.
$scope.$watch(function() { return fbsUserDataService.user; }, this.userChanged);
$scope.$watch(function() { return fbsUserDataService.initialized; }, this.userChanged);
}
]);
Service Code
'use strict';
angular.module('forbesArticleApp').service('contribEmailService', [
'$injector', '$route', 'ArticleAppState', 'fbsUserFormFactory', 'fbsUserDataService',
function initForm ($injector, $route, ArticleAppState, fbsUserFormFactory, fbsUserDataService) {
console.log("Hello world!");
}
]);
I only want to fire the contribEmailService.initForm() function from the call in my controller, but it is firing as soon as the page loads.
How do I set when the service function initForm() is called?
Here is the corrected service code:
'use strict';
angular.module('forbesArticleApp').service('contribEmailService', [
'$injector', '$route', 'ArticleAppState', 'fbsUserFormFactory', 'fbsUserDataService',
function($injector, $route, ArticleAppState, fbsUserFormFactory, fbsUserDataService) {
return {
initForm: function() {
console.log("Hello world!");
}
};
]);
The service function is a factory that will in turn return the actual service. So it will run the first time it is requested as a dependency. The way you had it written, in fact, contribEmailService would have been undefined within your function, because your factory didn't actually return anything.
Hope this helps!
controller:-
blogcontroller is controller name
app.controller('blogController', function($scope, $compile, $http, blogAuth, AppInfo, $location,$element){
$scope.blog_abuse = function(blog_id)
{
blogAuth.BlogAbuse(blog_id).then(function(response)
{
$scope.DetailblogList.is_abused = response.records.is_abused;
},function(error){
});
}
});
service:-
app.factory('AppInfo', function(){
return {
serviceURL:site_url
};
});
app.service('blogAuth', function($http, $rootScope, $q, AppInfo){
this.BlogAbuse = function(blog_id){
var deferred = $q.defer();
var pageObj ={"blog_id":blog_id};
$http.post(AppInfo.serviceURL+'blog/blog_abuse',pageObj).success(function(data){
deferred.resolve(data);
}).error(function(msg, code) {
console.log('error', code, msg );
});
return deferred.promise;
}
});

$scope variable being undefined despite being set inside a $watch function

I'm trying to insert some things into my Firebase database using a user's uid but it comes out undefined for some reason. Take a look at the code below:
The main controller that sets the user's data information (authData) when the page loads:
flickrApp.controller('mainCtrl', ['$scope', '$rootScope', '$firebase', 'Auth', 'shared', function($scope, $rootScope, $firebase, Auth, shared) {
Auth.$onAuth(function(authData) {
shared.setAuth(authData);
$scope.authData = shared.getAuth();
});
}]);
The service which handles the authentication state and shares it across my controllers:
flickrApp.service('shared', function() {
var authentication = false;
return {
getAuth: function () {
return authentication;
},
setAuth: function (auth) {
authentication = auth;
}
};
});
Here is where it doesn't work, in my tags controller. The $scope.authData is being set correctly in the $watch function but when I try to use it in the var ref line it says that $scope.authData is undefined (so therefore I can't access the uid). I can't figure out why this isn't working as it should be..
Do I have to use $apply with the watcher function as well or what is wrong?
flickrApp.controller('tagsCtrl', ['$scope', '$rootScope', '$firebase', 'shared', function($scope, $rootScope, $firebase, shared) {
$scope.tagsList = [];
$scope.shared = shared;
$scope.$watch('shared.getAuth()', function(authData) {
$scope.authData = authData;
console.log($scope.authData);
});
var ref = new Firebase ('https://flickr.firebaseio.com/users/' + $scope.authData.uid);
var sync = $firebase(ref);
$scope.addTag = function(tag) {
$scope.tagsList.push(tag);
sync.$set({favoriteTags: $scope.tagsList});
}
}]);
I think the issue is, assignment to ref is being done before the data of $scope.authData is set in $watch. Try to change your code to this:
flickrApp.controller('tagsCtrl', ['$scope', '$rootScope', '$firebase', 'shared', function($scope, $rootScope, $firebase, shared) {
$scope.tagsList = [];
$scope.shared = shared;
var ref,sync;
$scope.$watch('shared.getAuth()', function(authData) {
$scope.authData = authData;
console.log($scope.authData);
if($scope.authData){
ref = new Firebase ('https://flickr.firebaseio.com/users/' + $scope.authData.uid);
sync = $firebase(ref);
}
});
$scope.addTag = function(tag) {
$scope.tagsList.push(tag);
sync.$set({favoriteTags: $scope.tagsList});
}
}]);

Categories