Call function from another Controller in another file AngularJS - javascript

Call function from another Controller Angular Js
Call function from another controller Angularjs
http://tutorials.jenkov.com/angularjs/dependency-injection.html
I've been googling around and trying to adapt but I can't figure out.
I have two files: home.js and auth.js. I created the file auth.js because I will need to call the functions inside of it in lot of files.
I can't create simple functions like:
function isAuthed(){
return true;
}
Because I'll need to use some AngularJS modules, such as HTTP, therefore I believe I need to create a decent angular js file.
For what I've read so far, in order to call a function from another controller the best and correct way is to use Services.
home.js
var app = angular.module('home', [
'ngRoute'
]);
app.controller('home', ['$scope', 'authSERVICE', function($scope, authSERVICE){
console.log(authSERVICE.hasCredentials());
}]);
auth.js
var app = angular.module('auth', []);
app.service('authSERVICE', ['$http', function($http){
this.hasCredentials = function(){
if(window.localStorage.getItem('email') != null && window.localStorage.getItem('password') != null){
return true;
}
}
this.login = function(email, password){
// Base64 function is from a simple JS file.
var auth = Base64.encode('username:password');
$http.get('http://localhost/project/api/webservice/getCategories', {
headers: { 'Authorization': 'Basic ' + auth },
params : {
email: email,
password: password,
}
}).success(function(response){
return true;
}).error(function(response){
return false;
});
}
}]);
This does not work and I receive an error on console poiting to: https://docs.angularjs.org/error/$injector/unpr?p0=authSERVICEProvider%20%3C-%20authSERVICE
I kind of understand what's the error information telling me. Although, I still need and want to have two different files.
EDIT: Btw, in the index.html file I've called the scripts:
<script type="text/javascript" src="application/controllers/home.js"></script>
<script type="text/javascript" src="application/controllers/auth.js"></script>

Thanks to #Ved answer I manage to figure it out. Solved.
var app = angular.module('home', [
'ngRoute',
'auth'
]);

Related

How to make factory data available before controller loads page in angularJS

I am making an $http call using factory and sharing the data to all controllers.
Actually I am getting that data from config.json file, but first on load data is not getting broadcasted to all controllers.
I want data to be available before controller can make further calls inside.
My config.json has app_key, app_secret, base_url etc, here is my factory (JS code)
JS
.factory('UserService', function($http, $rootScope) {
$http.get('config.json').success(function(data) {
var app_key = data.app_key;
var app_secret = data.app_secret;
var base_url=data.base_url;
window.localStorage['app_key'] = app_key;
window.localStorage['app_secret'] = app_secret;
window.localStorage['base_url'] = base_url;
})
return {
app_key : window.localStorage['app_key'],
app_secret : window.localStorage['app_secret'],
base_url:window.localStorage['base_url'],
}
})
my config.json file looks like this
{
"app_key" : "my_app_key_here",
"app_secret" : "my_app_secret_here",
"base_url" : "http://base_url.com",
}
The reason I am returning app_key: window.localStorage['app_key'] is just because I need to access this service data like userService.app_key in controller.
ngoApp.controller('loginCtrl',['$scope','$http', '$localStorage', '$state','UserService','$rootScope', function($scope, $http, $localStorage, $state, UserService, $rootScope) {
//I want to access app_key as below format
$scope.app_key=UserService.app_key;
}]);
Can anyone please tell me what mistake I am making?
The right place where to load this dependencies is in your module run/config method.
Check documentation here: https://docs.angularjs.org/guide/module#module-loading-dependencies for example and more information...

Angular dependency injection does not recognise module

I'm having trouble properly injecting a bunch of modules in a project. This is the project I’m following
https://thinkster.io/django-angularjs-tutorial
When i try to make a new post - angular throws the below error
Error: Authentication.getAuthenticatedAccount(...) is undefined
submit#http://localhost:8000/static/javascripts/posts/controllers/new-post.controller.js:31:21
$parseFunctionCall#http://localhost:8000/static/bower_components/angular/angular.js:12474:15
This is where the problem seems to occur
function NewPostController($rootScope, $scope, Authentication, Snackbar, Posts) {
var vm = this;
vm.submit = submit;
function submit() {
$rootScope.$broadcast('post.created', {
content: vm.content,
author: {
username: Authentication.getAuthenticatedAccount().username
}
});
$scope.closeThisDialog();
Posts.create(vm.content).then(createPostSuccessFn, createPostErrorFn);
function createPostSuccessFn(data, status, headers, config) {
Snackbar.show('Success! Post created.');
}
function createPostErrorFn(data, status, headers, config) {
$rootScope.$broadcast('post.created.error');
Snackbar.error(data.error);
}
}
}
But I can see that the correct module is being used in the code.
this is my new-post.controller.js file where i've injected the Authentication dependency
angular
.module('thinkster.posts.controllers')
.controller('NewPostController', NewPostController);
NewPostController.$inject = ['$rootScope', '$scope', 'Authentication', 'Snackbar', 'Posts'];
this is a snippet my posts.module.js file
angular
.module('thinkster.posts', [
'thinkster.posts.controllers',
'thinkster.posts.directives',
'thinkster.posts.services'
]);
angular
.module('thinkster.posts.controllers', []);
this is a snippet of the authentication service module
angular
.module('thinkster.authentication.services')
.factory('Authentication',Authentication);
Authentication.$inject = ['$cookies','$http'];
function Authentication($cookies,$http){
var Authentication = {
getAuthenticatedAccount: getAuthenticatedAccount,
isAuthenticated: isAuthenticated,
register:register,
login : login,
logout:logout,
setAuthenticatedAccount: setAuthenticatedAccount,
unAuthenticate: unAuthenticate
};
return Authentication;
function getAuthenticatedAccount(){
if (!$cookies.authenticatedAccount){
return;
}
return JSON.parse($cookies.authenticatedAccount);
}
And a snippet of the authentication module
angular
.module('thinkster.authentication',[
'thinkster.authentication.controllers',
'thinkster.authentication.services'
]);
-finally, the below thinkster module
angular
.module('thinkster', [
'thinkster.config',
'thinkster.routes',
'thinkster.authentication',
'thinkster.layout',
'thinkster.posts',
'thinkster.utils'
]);
the authentication service works fine since I’m able to login and logout of the project. Am i looking in the wrong place for the error?
The code snippets are missing the NewPostController definition. Without seeing that code, I would guess that the Authentication object may not be passed into the function.
function NewPostController($rootScope, $scope, Authentication, Snackbar, Posts) {
}
You can see what methods are available on your Authentication object with the following code in NewPostController:
for (var key in Authentication) {
console.log(typeof Authentication[key], key);
}
You should see "function getAuthenticatedAccount" if it's available on the object.

Angular list/detail view

I'm fairly new to Angular and I'm wondering how to go about creating a list/detail view using Angular routes as what I currently have doesn't seem to be working.
The app has a list of 'projects' and when you click on a project you see a detailed view of that selected project, standard stuff. I've got this working using ng-switch but ideally I want to use seperate routes for the list/detail views. I've read that for this I'm going to need to use a factory method but I'm having difficulty passing the selected data between the routes. Here's what I have:
app.factory('Project', [ function ($rootScope) {
var _selectedProject = {};
_selectedProject.project = {};
return _selectedProject;
}]);
app.controller('GalleryController', ['$scope', function ($scope, _selectedProject) {
$scope.sharedProject = _selectedProject || {};
$scope.selectProject = function (proj) {
_selectedProject.project = proj;
};
$scope.$watch('sharedProject', function (proj) {
$scope.chosenProject = proj;
})
}]);
I'm actually getting cannot set property 'property' of undefined which is inside $scope.selectedProject.
A nice solution for this is ui-router.
ui-router allows the nesting of states which correspond to controllers, urls and html templates.
In your example I would do the following:
Install ui-router (described in the link above)
Apply a configuration as follows:
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('project', {
url: "/project",
templateUrl: "partials/project/list.html",
controller: project_list_controller
})
.state('project.details', {
url: "/details",
templateUrl: "partials/project/details.html",
controller: project_detail_controller
})
}
Split your current controller into a project list controller and a project details controller.
Finally I would use a service to store your selectedProject as its a singleton, see the correct useage and differences between services and factories in this helpful blog post
Hope this helps.
You named your factory Project but are using _selectedProject as the injection to controller. You also didn't include it in the injection array
Controller should look more like:
app.controller('GalleryController', ['$scope','Project', function ($scope, Project) {
$scope.sharedProject = Project || {};
$scope.selectProject = function (proj) {
Project.project = proj;
};
$scope.$watch('sharedProject', function (proj) {
$scope.chosenProject = proj;
});
}]);

Angular CRUD for more than one model object in one application

I have an Angular application that has three different business objects which require CRUD operations to be implemented on all of them independently. Let's call them a,b,c. I have equivalent aCtrl,bCtrl,cCtrl and aSvc,bSvc,cSvc to manage these CRUD operations.
So in this example, aCtrl manages CRUD for 'a'. aSvc helps persist the data to the backend with an ajax call.
I also have an allCtrl and allSvc which pulls all the objects a,b,c together from the backend in one json object when the application loads for the first time (instead of pulling them separately, I designed the backend to push one unified json object with embedded a,b,c in it.
The 'all' object
{
a:{},
b:{},
c:{}
}
so I'm stuck in structuring the app in a straightforward meaningful way. When the app loads for the first time, I'll have 'all' object pulled in by the allSvc from the backend. This has all the data needed to perform CRUD (of course I have to keep it in sync with the backend). And when the app loads for the first time, I want to list the objects of type 'a' and then give the user options to edit/delete/add. Similarly, I have drop down navigation to do take the user to other pages that do exactly the same for object 'b', 'c'.
Here are some snippets of what I did so far and how I fail miserably :)
index.html
<html lang="en" ng-app="myApp">
...
...
<div class="" ng-view></div>
js
var myApp = angular.module('myApp', ['ngRoute','restangular']);
myApp.controller('aCtrl', function($scope, aSvc)
myApp.controller('bCtrl', function($scope, bSvc)
myApp.controller('cCtrl', function($scope, cSvc)
myApp.controller('allCtrl', function($scope, allSvc)
routes
myApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/a/list', {templateUrl: 'partials/a/list.html',controller: 'aCtrl'});
$routeProvider.when('/a/add', {templateUrl: 'partials/a/add.html', controller: 'aCtrl'});
$routeProvider.when('/a/edit/:id', {templateUrl: 'partials/a/edit.html', controller: 'aCtrl'});
$routeProvider.when('/a/delete/:id', {templateUrl: 'partials/a/list.html', controller: 'aCtrl'});
.... similary I have routes for b & c to perform crud
$routeProvider.otherwise({redirectTo: '/a/list'});
}]);
aCtrl
myApp.controller('aCtrl', function($scope, aSvc,allSvc) {
$scope.allCollection= allService.getAll();
$scope.aCollection = allCollection.a;
I'm unable to meaningfully setup routeParams in this design to perform edit/delete properly. I also have to account for the userId (the user who logs in for whom the CRUD operations need to be performed). How do I better manage the routes? should I use something like /a/edit/userId/aId for editing 'a' and /a/delete/userId/aId to delete 'a' as an example?
Please help me polish this turd.
I have separated the service/update/request calls in a controller and the project can be found at the below path. Let me know if anyone thinks it can be improved further. However, to test the services, I have used strongloop and the description can be found at the repository itself.
Angular - Create, Update, Delete
The sample would look like this:
'use strict';
function MainController($scope, $state, $rootScope, $window, $stateParams, HttpService) {
$scope.init = function () {
HttpService.load("http://0.0.0.0:3000/api/custdetails")
.then(function (response) {
if (response) {
console.log(JSON.stringify(response.data));
$scope.showAllData = response.data;
}
}, function (error) {
console.log("Error occurred");
});
};
$scope.addMoreData = function () {
var data = {
cust_name: $scope.custNameModel,
phone_number: $scope.phoneNumberModel,
id: $scope.idModel
};
HttpService.update('http://0.0.0.0:3000/api/custdetails?', data);
$scope.init();
};
$scope.updateData = function () {
var data = {
cust_name: $scope.custNameModel,
phone_number: $scope.phoneNumberModel,
id: $scope.idModel
};
HttpService.patch('http://0.0.0.0:3000/api/custdetails?', data);
$scope.init();
};
$scope.deleteData = function () {
console.log("ID defined is: " + $scope.idModel);
HttpService.delete("http://0.0.0.0:3000/api/custdetails", $scope.idModel);
$scope.init();
};
}

Argument 'fn' is not a function got string

I have a part in my angular application on which I've binded a controller,
since then I got the Argument 'fn' is not a function Error, can anyone look at my code and explain why I got that Error?
I would be very gratefull :)
html-markup:
<section class="col-lg-12" data-ng-controller="MessageController">
<fieldset>
<legend>{{ 'MESSAGES' | translate }}</legend>
</fieldset>
<div class="margin-left-15">
<ul class="list-style-button">
<li data-ng-repeat="message in MSG">{{ message }}</li>
</ul>
</div>
</section>
controller:
(function() {
'use strict';
var controllers = angular.module('portal.controllers');
controllers.controller('MessageController', ['$scope', 'MessageService', '$rootScope', function MessageController($scope, MessageService, $rootScope) {
$rootScope.MSG = MessageService.getMessages();
$rootScope.$watch('MSG', function(newValue) {
$scope.MSG = newValue;
});
}]);
}());
Service:
(function() {
'use strict';
var messageServices = angular.module('portal.services');
messageServices.factory('MessageService', ['MessageData', 'localStorageService', 'UserService'], function(MessageData, localStorageService, UserService) {
return new MessageService(MessageData, localStorageService, UserService);
});
function MessageService(MessageData, localStorageService, UserService) {
this.messageData = MessageData;
this.localStorageService = localStorageService;
this.userService = UserService;
}
MessageService.prototype.getMessages = function() {
var locale = this.userService.getUserinfoLocale();
var messages = this.localStorageService.get(Constants.key_messages + locale);
if (messages !== null && messages !== undefined) {
return JSON.parse(messages);
} else {
return this.messageData.query({
locale: locale
}, $.proxy(function(data, locale) {
this.save(Constants.key_messages + locale, JSON.stringify(data));
}, this));
}
};
MessageService.prototype.save = function(key, value) {
this.localStorageService.add(key, value);
};
}());
data:
(function() {
'use strict';
var data = angular.module('portal.data');
data.factory('MessageData', function($resource) {
return $resource(Constants.url_messages, {}, {
query: {
method: 'GET',
params: {
locale: 'locale'
},
isArray: true
}
});
});
}());
order of js files in html head:
<script src="js/lib/jquery-1.10.js"></script>
<script src="js/lib/angular.js"></script>
<script src="js/lib/angular-resource.js"></script>
<script src="js/lib/angular-translate.js"></script>
<script src="js/lib/angular-localstorage.js"></script>
<script src="js/lib/jquery-cookies.js"></script>
<script src="js/lib/bootstrap.js"></script>
<script src="js/portal.js"></script>
The problem was in using the 'wrong' syntax to create the service
instead of using:
messageServices.factory('MessageService',
['MessageData','localStorageService', 'UserService'],
function(MessageData, localStorageService, UserService){
return new MessageService(MessageData, localStorageService, UserService);
}
);
I had to use:
messageServices.factory('MessageService',
['MessageData','localStorageService', 'UserService',
function(MessageData, localStorageService, UserService){
return new MessageService(MessageData, localStorageService, UserService);
}
]);
I closed the array with parameters to soon, and since I'm still learning I didn't see it directly, anyhow I hope I can help others who stumble upon this.
Today I got the same kind of error doing that silly mistake:
(function(){
angular
.module('mymodule')
.factory('myFactory', 'myFactory'); // <-- silly mistake
myFactory.$inject = ['myDeps'];
function myFactory(myDeps){
...
}
}());
instead of that:
(function(){
angular
.module('mymodule')
.factory('myFactory', myFactory); // <-- right way to write it
myFactory.$inject = ['myDeps'];
function myFactory(myDeps){
...
}
}());
In fact the string "myFactory" was brought into the injector who was waiting for a function and not a string.
That explained the [ng:areq] error.
The above answers helped me considerably in correcting the same issue I had in my application that arose from a different cause.
At built time, my client app is being concatenated and minified, so I'm writing my Angular specifically to avoid related issues. I define my config as follows
config.$inject = [];
function config() {
// config stuff
}
(I define a function, $inject it as a module and declare what it is).
And then I tried to register the config just as I registered other modules in my app (controllers, directives, etc..).
angular.module("app").config('config', config); // this is bad!
// for example, this is right
angular.module("app").factory('mainService', mainService);
This is wrong, and gave me the aforementioned error. So I changed to
angular.module("app").config(config);
And it worked.
I guess the angular devs intended config to have a singular instance and by so having Angular not accept a name when config is registered.
I had the same issue and In my case the problem was with angular-cookies.js file. It was in folder with other angularjs scripts and when I have used gulp to minify my js files the error occured.
Simple solution was just to place the angular-cookies.js file to another folder, outside the selected folder to minify js files.
My case
let app: any = angular.module("ngCartosServiceWorker"),
requires: any[] = [
"$log",
"$q",
"$rootScope",
"$window",
"ngCartosServiceWorker.registration",
PushNotification
];
app.service("ngCartosServiceWorker.PushNotification");
I forgot to add requires Array as parameters to service like this
app.service("ngCartosServiceWorker.PushNotification", requires);

Categories