Access modules child modules service from main controller - javascript

I have this module as my main app which uses api:
var app = angular.module('app.main', ['api']);
app.controller('Home', function($scope, api, search){
$scope.search = function(){
api.search.lookup($scope.domain);
search.lookup($scope.domain);
};
});
I then have api which uses a few other modules like this:
var app = angular.module('api', [
'api.search'
// other modules here
]);
app.service('api', function($cookies, $http, $rootScope, search){
// Some more code
});
The search search module looks like this:
var app = angular.module('api.search', []);
app.service('search', function($scope, $http){
this.lookup = function(domain){
// query
};
});
When I run my controller and inject api, I can not access search because I get TypeError: Cannot read property 'lookup' of undefined, and if I inject search instead, I get this error:
Error: [$injector:unpr] http://errors.angularjs.org/1.4.3/$injector/unpr?p0=<div ng-view="" class="ng-scope" data-ng-animate="1">copeProvider%20%3C-%20%24scope%20%3C-%search
So, how can I access search from my controller?

The problem, as it seems, is that you are trying to inject $scope into a service generating function.
$scope is a local injectable available only for controllers, which makes sense, since scope is contextual to where the controller is defined and it has no meaning for singleton services.
Instead, you could inject $rootScope into a service, if needed.
app.service('search', function($rootScope, $http){
// ...
});

Related

angularjs 1.5 injecting service in a component - uknown provider error

I want to share a specific property across different components' (different controllers in them).
Trying to inject a service that I created in the app module.
The service has get/set functions.
I created the service called SharedProperties. It's not accessible from any component in my app, says "Uknown". Why?
This is how my app is defined, and here's the very simple service.
mapotApp = angular
.module('mapotApp', [])
.service('sharedProperties', function () {
var property = 'test';
return {
getProperty: function () {
return property;
},
setProperty: function(value) {
property = value;
}
};
});
and then in my component:
angular.module('aboutPage').component('aboutPage', {
templateUrl: 'app/about-page/about-page.html',
controller: ['sharedProperties', function AboutPageController($http, $scope, sharedProperties) {
var self= this;
//inherting global variable
self.prop = sharedProperties.getProperty(); //UNKOWN PROVIDER ERROR HERE
}]
});
This returns:
Error: [$injector:unpr] Unknown provider: sharedPropertiesProvider <- sharedProperties
What can I do?
I tried injecting it in tons of places and still doesn't work.
thanks so much.
Here is the working DEMO with your code.
Your shareable service is correct, but make sure to properly initialize your controller, as well as correctly inject $http and $scope in it (see how $scope and $timeout services are injected in my demo).

How to use constants defined in one file in another in angularjs

Well I have seen couple of questions in StackOverFlow related to this but couldn't find proper answer.
Say in my app.js file I have defined a constants object which basically has controllers names. As I use "ui-router" I want to attach Controllers to views on state change.
app.js
var app = angular.module('myApp', ['ui.router']);
app.constant('CONTROLLER', {
ONE: 'ControllerOne',
TWO: 'ControllerTwo'
});
Now I want to use those constants to define Controller names in other file, say controller.js. Illustrating couple of ways which I tried but dint work for me.
controller.js
var app = angular.module('myApp', ['CONTROLLER']);
app.controller(CONTROLLER.ONE, ['$scope', 'myFactory', function ($scope, myFactory) {
$scope.result = myFactory.someAPI();
}]);
ERROR -> Uncaught ReferenceError: CONTROLLER is not defined
Even I tried injecting that constant module in Controller which gave same error.
var app = angular.module('myApp', ['CONTROLLER']);
app.controller(CONTROLLER.ONE, ['$scope', 'myFactory', 'CONTROLLER', function ($scope, myFactory, CONTROLLER) {
$scope.result = myFactory.someAPI();
}]);
I know that second way is wrong. As I define controller names in my main app.js file and use those constants to attach controllers to views during state change.
I want reuse those constants to define controllers names too.
I may be doing something wrong. Any suggestions ?
Your code shows that you have correctly injected the CONTROLLER constant into the controller constructor function.
var app = angular.module('myApp', ['CONTROLLER']);
app.controller(CONTROLLER.ONE, ['$scope', 'myFactory', 'CONTROLLER', function ($scope, myFactory, CONTROLLER) {
// use constant here
}]);
That being said you can only access the constant except from within the controller function itself. The names of controllers, services, factories etc must be accessible strings, which is not the case until the constant has been injected.
You could use a plain old JavaScript object outside angular to define the names.
var CONTROLLER = {
ONE: 'ControllerOne',
TWO: 'ControllerTwo'
});
I can only guess that you are trying to do this because the controller or directive you are writing will be referenced/used at multiple points throughout your html.

$scope is not defined in service AngularJs:

got error of scope not defined when i use for response message:
$scope.responsemessage = response;
then I added $scope here like this:
app.service('fileUpload', ['$http', '$scope', function ($http, $scope) {
When I added above $scope got this error Error: [$injector:unpr]
http://errors.angularjs.org/1.4.8/$injector/unpr?p0=.................
Service don't have scope.
If you wanna to use scope inside service , have to pass it from controller .
Like this
In controller
fileUpload.checkFile($scope.responsemessage);
In service
function checkFile(respMsg)
{
console.log(respMsg);
}
$scopes are not available from services, it should only be used inside controllers.
In angular $scope is available in controllers and services are used as a dependency for data provider.
You just can't use $scope in the service and from service you can return a promise object like:
app.service('fileUpload', ['$http', function($http) {
return $http.post('url')
}]);
Now you can inject this service to update a variable on the controller's $scope:
app.controller('cntrl', ['$scope', 'fileUpload', function($scope, fileUpload){
$scope.responsemessage = fileUpload.then(function(data){
return data;
})
}]);
You can not use $scope in Services as well as in Factories.
You can call service by giving $scope value as a parameter and save the return value to the $scope variable

Why can't I inject my service?

I have the following new service:
var SignatureService = function ($scope) {
this.announce = function () {
alert($scope.specificName);
}
};
SignatureService.$inject = ['$scope'];
This is declared for the app as follows:
MyAngularApp.service('SignatureService', SignatureService);
Several other services are added to the app in exactly the same way, and they all seem to work OK. I then have a controller declared and defined as follows:
MyAngularApp.controller('MyController', MyController);
...
var MyController = function ($scope, Service1, Service2, $location, $modal, SignatureService) {
...
}
MyController.$inject = ['$scope', 'Service1', 'Service2', '$location', '$modal', 'SignatureService'];
I am simply using the slightly unconvcentionaly manner of defining the servivce and injecting it that is standard in the app I am working on, as this works for all existing services, and I would prefer to simply slot mine in as per standard.
When the controller loads, I get an [$injector:unpr] in the browser console, with the error info:
$injector/unpr?p0=$scopeProvider <- $scope <- SignatureService
You can't inject $scope into your custom service. It just doesn't make sense since SignatureService can be injected anywhere including other services and other controlles. What $scope is supposed to be if you say inject it into two nested controllers, which one should be injected?
Scope object ($scope) is always associated with some DOM node, it is attached to it. That's why you see $scope in controllers and directives. And this is the reason why you can't have it in service: services are not related to specific DOM elements. Of course you can inject $rootScope but this is unlikely what you need in your question.
Summary: $scope is created from the $rootScope and injected in necessary controllers, but you can't injected it into custom service.
UPD. Based on comments you want to use service to define reusable controller methods. In this case I would go with what I call mixin approach. Define methods in the service and mix them in the necessary controllers.
app.service('controllerMixin', function() {
this.getName = function() {
alert(this.name);
};
});
and then extend controller scope with angular.extend:
app.controller('OneController', function($scope, controllerMixin) {
angular.extend($scope, controllerMixin);
// define controller specific methods
});
app.controller('TwoController', function($scope, controllerMixin) {
angular.extend($scope, controllerMixin);
// define controller specific methods
});
This is pretty effective, because controllerMixin doesn't have any notion of $scope whatsoever, when mixed into controller you refer to the scope with this. Also service doesn't change if you prefer to use controllerAs syntax, you would just extend this:
angular.extend(this, controllerMixin);
Demo: http://plnkr.co/edit/ePhSF8UttR4IgeUjLRSt?p=info

AngularJS: Inject controller inside another controller from the same module

Is possible to inject a controller into another controller that is part of the same module?
example:
var app = angular.module('myAppModule', [])
.controller('controllerOne', ['$scope', function($scope){
$scope.helloWorld = function(){
return 'Hello World';
}
}])
.controller('controllerTwo', ['$scope', 'controllerOne', function($scope, controllerOne){
console.log(controllerOne.helloWorld());
}])
I keep getting unknown provider on controllerOne. I don't see how that's possible since they coexist in the same module. Any help would be much appreciated.
You need to use $controller dependency by using that you can inject one controller to another
.controller('controllerTwo', ['$scope', '$controller', function($scope, $controller){
$controller('controllerOne', {$scope: $scope})
//inside scope you the controllerOne scope will available
}]);
But do prefer service/factory to share data
Move your logic into a "service" (either a factory/service/provider). I personally prefer factories, I just like controlling my own object instead of using this or anything like that with the other options.
Using a service, you give yourself the ability to abstract business logic from your controllers, and make that logic -- reusable -- !
var app = angular.module('myAppModule', [])
// typically people use the word Service at the end of the name
// even if it's a factory (it's all the same thing really...
.factory('sharedService', function () {
var methods = {};
methods.helloWorld = function () {
return 'Hello World!';
};
// whatever methods/properties you have within this methods object
// will be available to be called anywhere sharedService is injected.
return methods;
})
Notice sharedService is injected
.controller('ControllerOne', ['$scope', 'sharedService', function($scope, sharedService) {
$scope.helloWorld = sharedService.helloWorld();
}])
// Notice sharedService is injected here as well
.controller('ControllerTwo', ['$scope', 'sharedService', function($scope, sharedService){
// Now we can access it here too!
console.log( sharedService.helloWorld() );
}]);
Side note : Controllers should be capitalized to show their significance!
The power of services :)
If the a controllerTwo needs to call the same function as controllerOne, you may want to create a service to handle it. Angular Services - they are accessible throughout your program through dependency injection.
var app = angular.module('myAppModule', [])
.controller('controllerOne', ['$scope', 'Hello', function($scope, Hello){
console.log(Hello.helloWorld() + ' controller one');
}])
.controller('controllerTwo', ['$scope', 'Hello', function($scope, Hello){
console.log(Hello.helloWorld() + ' controller two');
}])
.factory('Hello', [function() {
var data = {
'helloWorld': function() {
return 'Hello World';
}
}
return data;
}]);
Hope this helps!
You cannot inject controllers in another controllers,only serviceProviers are injectable.That's the reason you are getting error as unkown provider in controller one.
Use Services instead and inject them in controllers,if there is some come functionality to be shared among controllers.Services are the best way to share data in between controllers.
You can declare a variable or function or say object on $rootScope, it's exists in your whole application.
Share data between AngularJS controllers

Categories

Resources