AngularJS Call function from another file - angularjs

When I trying call function from another file I get error:
TypeError: Cannot read property 'getCurrentUserFullName' of undefined
in app.js:
'use strict';
var testApp = {};
var App = angular.module('testApp', ['testApp.filters', 'testApp.services', 'testApp.directives',
'ngRoute']);
App.run(['$location', '$rootScope', function ($location, $rootScope) {
$rootScope.$on("$routeChangeSuccess", function (event, currentRoute, previousRoute, AuthUtils) {
if(!$rootScope.userFullName){
var userFullName = AuthUtils.getCurrentUserFullName();
if(userFullName) {
$rootScope.userFullName = userFullName;
$rootScope.authenticate = true;
} else {
$rootScope.authenticate = false;
$rootScope.userFullName = "";
}
}
});
}]);
AuthUtils.js
'use strict';
angular.module('testApp')
.factory('AuthUtils', function AuthUtils($rootScope, $http) {
return {
getCurrentUserFullName: function () {
$http.get('auth/userFullName').success(function (user) {
return user;
}).error(function (data, status) {
return "error";
console.error(status, data);
});
}
};
});
Why doesn't work?

You missed to inject AuthUtils inside run block. Inject it so factory instance would be available in run block
App.run(['$location', '$rootScope', 'AuthUtils', //<== injected AuthUtils here
function ($location, $rootScope, AuthUtils) { //<== and here
Additonally you need to remove AuthUtils parameter from $routeChangeSuccess function, which was killing existence of injected AuthUtils in run block.
Change to
$rootScope.$on("$routeChangeSuccess", function (event, currentRoute, previousRoute) //<--removed AuthUtils
From
$rootScope.$on("$routeChangeSuccess", function (event, currentRoute, previousRoute, AuthUtils)

Related

Factory Service is always undefined

I've spent a few hours trying to debug this with no real breakthroughs. My console.logs correctly output the load order.
- app
- factory
- controller
I'm annotating my dependencies (even though I'm not minifying at the moment).
Is there anything obviously wrong here that I am missing?
error
app
(function () {
'use strict';
console.log("running app");
var app = angular.module('InventoryProductApp', []).config(function ($logProvider) {
$logProvider.debugEnabled(true);
});
angular.element(document).ready(function () {
var app = document.getElementById('InventoryProductApp');
angular.bootstrap(angular.element(app), ['InventoryProductApp']);
});
})();
controller
(function () {
'use strict';
angular.module('InventoryProductApp').controller("LocationsController", ['$scope', '$log', 'LocationsFactory'
, function ($scope, $http, $log, LocationsFactory) {
console.log("running controller");
$scope.locations = null;
$scope.loading = false;
//private methods -------------------------------------------------------------------------------------------------------------------------------------------------------------
var fetchLocationData = function (inventoryId) {
$scope.loading = true;
console.log(LocationsFactory);
var promise = LocationsFactory.getLocationData(inventoryId);
promise.then(function (data) {
$scope.loading = false;
if (data.success) {
$scope.locations = data.locations;
}
else
{
$log.error('There was an error getting location data');
}
}, function (data) {
$scope.loading = false;
$log.error('There was an error getting location data');
});
}
//end private methods ---------------------------------------------------------------------------------------------------------------------------------------------------------
//public methods --------------------------------------------------------------------------------------------------------------------------------------------------------------
var init = function (inventoryId) {
console.log('inventoryId', inventoryId);
fetchLocationData(inventoryId);
}
//end public methods ----------------------------------------------------------------------------------------------------------------------------------------------------------
init(inventoryId); // inventoryId is found in the partialView _inventoryLocationDistribution
}]);
})();
factory
(function () {
'use strict';
angular.module('InventoryProductApp').factory('LocationsFactory', ['$http', '$q', '$log', function ($http, $q, $log) {
console.log("running factory");
return {
getLocationData: function (inventoryId) {
var def = $q.defer();
$http.get('/butthead', {
params: {
inventoryId: inventoryId
}
}).then(function (response) {
def.resolve({
success: true,
locations: data.locations
});
}, function (response) {
$log.error('failed to fetch data', response);
def.resolve({
success: false,
redirect: response.redirect
});
});
return def.promise;
}
}
}]);
})();
script load order
<script src="~/theme/modern/assets/global/plugins/angularjs/angular.min.js"></script>
<script src="~/App/Inventory/Product/ProductApp.js"></script>
<script src="~/App/Inventory/Product/LocationsFactory.js"></script>
<script src="~/App/Inventory/Product/LocationsController.js"></script>
In your controller:
angular.module('InventoryProductApp').controller("LocationsController",
['$scope', '$log', 'LocationsFactory', function ($scope, $http, $log, LocationsFactory) {
You're missing '$http' in your dependency injections, which means the LocationsFactory argument isn't filled at all.

Issue with Angular.js and Angular Style Guide

I'm having an issue correctly getting a data service to work as I try to follow the Angular Style Guide (https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#data-services)
I'm sure it's something obvious to the more experienced but I can't get the data set to assign properly to the vm.items outside of the
Data Service
(function() {
'use strict';
angular
.module('portfolioApp')
.factory('portfolioService', portfolioService);
portfolioService.$inject = ['$http', 'logger'];
function portfolioService($http, logger) {
return {
getPortfolioData: getPortfolioData,
};
function getPortfolioData() {
return $http.get('./assets/portfolio/portfolioItems.json')
.then(getPortfolioDataComplete)
.catch(getPortfolioDataFail);
function getPortfolioDataComplete(response) {
return response.data;
}
function getPortfolioDataFail(error) {
logger.error('XHR Failed for getPortfolioData.' + error.data);
}
}
}
}());
Controller
.controller('portfolioController', ['$scope', '$http', '$stateParams', 'logger', 'portfolioService', function($scope, $http, $stateParams, logger, portfolioService) {
var vm = this;
vm.items = [];
activate();
function activate() {
return getData().then(function() {
logger.info('Activate the portfolio view');
});
}
function getData() {
return portfolioService.getPortfolioData()
.then(function(data) {
vm.items = data;
return vm.items;
});
}
console.log("test")
console.log(vm.items);
console.log("test")
}])
Your getData function is a promise, so it's run asynchronously. Your console.log are called before the end of the promise so the vm.items is still empty.
Try to put the log in the then callback.

Angularjs--factory is undefined

I am developing an application using MVC and angularjs and very new to angularjs. The code uses lot of different factory defined in separate js files and those factories are injected correctly in modules but still I see 'factory not defined error'
The app.js is below:-
(function () {
'use strict';
angular.module('MyApp', ['common.core', 'common.ui'])
.run(run);
run.$inject = ['$rootScope', '$location', '$cookieStore', '$http','membershipService'];
function run($rootScope, $location, $cookieStore, $http) {
// handle page refreshes
$rootScope.repository = $cookieStore.get('repository') || {};
if ($rootScope.repository.loggedUser) {
$http.defaults.headers.common['Authorization'] = $rootScope.repository.loggedUser.authdata;
}
}
})();
Factory is defined in separate file like this:-
(function (app) {
'use strict';
var app = angular.module('MyApp');
app.factory('membershipService', membershipService);
membershipService.$inject = ['apiService', 'notificationService','$http', '$base64', '$cookieStore', '$rootScope'];
function membershipService(apiService, notificationService, $http, $base64, $cookieStore, $rootScope) {
var service = {
login: login,
register: register,
saveCredentials: saveCredentials,
removeCredentials: removeCredentials,
isUserLoggedIn: isUserLoggedIn
}
function login(user, completed) {
apiService.post('/api/account/authenticate', user,
completed,
loginFailed);
}
function register(user, completed) {
apiService.post('/signup', user,
completed,
registrationFailed);
}
function saveCredentials(user) {
var membershipData = $base64.encode(user.username + ':' + user.password);
$rootScope.repository = {
loggedUser: {
username: user.username,
authdata: membershipData
}
};
$http.defaults.headers.common['Authorization'] = 'Basic ' + membershipData;
$cookieStore.put('repository', $rootScope.repository);
}
function removeCredentials() {
$rootScope.repository = {};
$cookieStore.remove('repository');
$http.defaults.headers.common.Authorization = '';
};
function loginFailed(response) {
notificationService.displayError(response.data);
}
function registrationFailed(response) {
notificationService.displayError('Registration failed. Try again.');
}
function isUserLoggedIn() {
return $rootScope.repository.loggedUser != null;
}
return service;
}
})(angular.module('common.core'));
The controller is defined like this:-
(function (app) {
'use strict';
var app = angular.module('MyApp');
app.controller('SignUpController', SignUpController);
SignUpController.$inject = ['$scope', 'membershipService', 'notificationService', '$rootScope', '$location'];
function SignUpController($scope, membershipService, notificationService, $rootScope, $location) {
$scope.pageClass = 'page-login';
$scope.register = register;
$scope.user = {};
};
function register() {
membershipService.register($scope.user, registerCompleted)
}
function registerCompleted(result) {
if (result.data.success) {
membershipService.saveCredentials($scope.user);
notificationService.displaySuccess('Hello ' + $scope.user.username);
$scope.userData.displayUserInfo();
$location.path('/');
}
else {
notificationService.displayError('Registration failed. Try again.');
}
}
})(angular.module('common.core'));
The script are loaded like below:-
bundles.Add(new ScriptBundle("~/bundles/Controllers").Include(
"~/Scripts/Controllers/app.js",
"~/Scripts/Services/apiService.js",
"~/Scripts/Services/notificationService.js",
"~/Scripts/Services/membershipService.js",
"~/Scripts/Services/fileUploadService.js",
"~/Scripts/Controllers/SignUpController.js"
The 'register' function throws an error 'membershipservice not defined', what am i doing wrong? Please help.
I'm seeing this:
run.$inject = ['$rootScope', '$location', '$cookieStore', '$http','membershipService'];
function run($rootScope, $location, $cookieStore, $http) {
// handle page refreshes
You are missing the membershipService in the function parameter list.
Also this:
SignUpController.$inject = ['$scope', 'membershipService', 'notificationService', '$rootScope', '$location'];
function SignUpController($scope, membershipService, notificationService, $rootScope, $location) {
$scope.pageClass = 'page-login';
$scope.register = register;
$scope.user = {};
};
function register() {
membershipService.register($scope.user, registerCompleted)
}
function registerCompleted(result) {
if (result.data.success) {
membershipService.saveCredentials($scope.user);
notificationService.displaySuccess('Hello ' + $scope.user.username);
$scope.userData.displayUserInfo();
$location.path('/');
}
else {
notificationService.displayError('Registration failed. Try again.');
}
}
This will never work, because you are defining the function outside of the function where you pass the membershipService into.
The SignUpController should look something like:
function SignUpController($scope, membershipService, notificationService, $rootScope, $location) {
$scope.pageClass = 'page-login';
$scope.register = register;
$scope.user = {};
function register() {
membershipService.register($scope.user, registerCompleted)
}
function registerCompleted(result) {
if (result.data.success) {
membershipService.saveCredentials($scope.user);
notificationService.displaySuccess('Hello ' + $scope.user.username);
$scope.userData.displayUserInfo();
$location.path('/');
}
else {
notificationService.displayError('Registration failed. Try again.');
}
}
};
See, in your method SignUpController that is where the DI will be injecting the parameters into.
However, you have defined the functions that require those parameters OUTSIDE the scope of SignUpController function

Call method of an controller in another controller angularjs

I try to call an method of civilitiyController in CustomerController. So, with my search I have found the event's manager to call method but I don't success to return the result from CivilityController to CustomerController.
I already tried this:
1/
civilitiesController :
$scope.$on("getListCivilities", function(event, args){
$scope.civilities = getCivilitiesList();
});
customersController :
$scope.$broadcast("getListCivilities");
console.dir($scope.civilities) // after run civilities = undefined
2/CivilitiesController:
$scope.$on("getListCivilities" , function(event, args){
var list = getCivilitiesList();
return list;
});
CustomersController :
$scope.civilities = $scope.$broadcast("getListCivilities");
console.dir($scope.civilities); //display var of broadcast
3/ Edit:
After first answer, I tried this :
civilities controller :
function getCivilitiesList()
{
var reqGetCivilities = $http({ url: 'api/Civilities/Get' });
reqGetCivilities.success(function(data){
$scope.civilities = data;
$scope.$broadcast("getListCivilities", { list: $scope.civilities });
return data;
});
}
getCivilitiesList();
customersController :
function test()
{
$scope.$on("getListCivilities", function (event, args) {
$scope.civilities = args.list;
console.log('test0');
console.dir($scope.civilities);
});
}
test();
$scope.$on is never executed and I don't see why.
I hope someone can help me.
check this plunker
app.controller('Controller1', function($scope) {
$scope.name = 'World';
$scope.$on('ValueUpdated', function(event, args) {
$scope.name = args.currentValue;
});
});
app.controller('Controller2', ['$rootScope', '$scope', function($rootScope, $scope) {
$scope.myData = "type here";
$scope.broadCast = function() {
$rootScope.$broadcast('ValueUpdated', {
currentValue: $scope.myData
});
}
I used broadcast, but you can do this with services and watchers too.
I guess below should work :
function CivilitiesController($scope)
{
$scope.$on('someEvent', function(event, args) {});
// another controller or even directive
}
function CustomersController($scope)
{
$scope.$emit('someEvent', args);
}
JSFiddle (for more details) : http://jsfiddle.net/nikdtu/moo89kaw/
Ahmet Zeytindalı, this is my entire CivilitiesController :
(function () {
'use strict';
'use strict';
angular
.module('LSapp')
.controller('CivilitiesCtrl', CivilitiesCtrl)
CivilitiesCtrl.$inject = ['$scope', '$http', '$rootScope'];
function CivilitiesCtrl($scope, $http, $rootScope) {
function getCivilitiesList()
{
var reqGetCivilities = $http({ url: 'api/Civilities/Get' });
reqGetCivilities.success(function(data){
$scope.civilities = data;
});
}
getCivilitiesList();
function getList()
{
$rootScope.$broadcast("getListCivilities", { list: $scope.civilities });
}
getList();
}
})();
And the method to retreive list:
(function () {
'use strict';
angular
.module('LSapp')
.controller('CustomersCtrl', CustomersCtrl)
CustomersCtrl.$inject = ['$scope', '$http', '$location', '$modal', '$window', '$compile','$cookies', '$state','locker','$q','$timeout', '$rootScope'];
function CustomersCtrl($scope, $http, $location, $modal, $window, $compile, $cookies, $state, locker, $q, $timeout) {
//some code
function test()
{
$scope.$on("getListCivilities", function (event, args) {
$scope.civilities = args.list;
console.log('$on args : ');
console.dir(args);
});
}
test();
}
});
The method $on doesn't run and if I put console.log($scope.civilities) after the method, the result is always undefined.

AngularJS - factory is an empty object

I'm new in AngularJS - I can't figure out why I get the error mainDataService.refreshStatus is not a function in the $scope.clickMe function. I see the mainDataService variable is an empty object besides its initialization. What am I doing wrong here ?
var mainDataService = {};
var firstModule = angular.module('myModule', ['ngRoute', 'ngAnimate']);
(function () {
var mainDataServiceInjectParams = ['$http', '$q'];
var mainFactory = function ($http, $q) {
mainDataService.refreshStatus = function (id) {
return $http.get('/api/values/' + id).then(function (results) {
return results.data;
});
};
return mainDataService;
};
mainFactory.$inject = mainDataServiceInjectParams;
firstModule = firstModule.factory('mainService', mainFactory);
}());
firstModule.controller('myCtrl', function ($scope, $http) {
$scope.TST = '1';
$scope.clickMe = function (id) {
mainDataService.refreshStatus(id).then(function (results) {
$scope.TST = results;
});
}
});
You need to use the dependency injection mechanism to load your own services.
Put the mainDataService declaration in a local scope and inject the mainService into myCtrl:
var firstModule = angular.module('myModule', ['ngRoute', 'ngAnimate']);
(function () {
var mainDataServiceInjectParams = ['$http', '$q'];
var mainFactory = function ($http, $q) {
var mainDataService = {};
mainDataService.refreshStatus = function (id) {
return $http.get('/api/values/' + id).then(function (results) {
return results.data;
});
};
return mainDataService;
};
mainFactory.$inject = mainDataServiceInjectParams;
firstModule = firstModule.factory('mainService', mainFactory);
}());
firstModule.controller('myCtrl', function ($scope, $http, mainService) {
$scope.TST = '1';
$scope.clickMe = function (id) {
mainService.refreshStatus(id).then(function (results) {
$scope.TST = results;
});
}
});
Even better, you should explicitly assign the dependencies into the controller, so that your code still works after minifcation (as you already did it for the service):
firstModule.controller('myCtrl', myCtrl);
myCtrl.$inject = ['$scope', '$http', 'mainService'];
function myCtrl($scope, $http, mainService) {
$scope.TST = '1';
$scope.clickMe = function (id) {
mainService.refreshStatus(id).then(function (results) {
$scope.TST = results;
});
}
});
As you see, if you use normal function definitions, you can make use the function hoisting of Javascript and write the functions at the end while having the relevant code at the top. It's the other way round as in your example of the service.
Supply mainService to controller
firstModule.controller('myCtrl', function ($scope, $http, mainService) {
and then use it in the function
mainService.refreshStatus
I think you immediately invoked function is not invoked so mainDataService still reference the object you set at the first line
(function(){})()
rather than
(function(){}())

Resources