I wrote a factory function for some restrict options for all the name fields and I want to use/call that factory globally throughout the application. How can I use the factory globally?
This is my code:
checks.factory('pasteOptions',function($event) {
var clipboarddata = window.event.clipboardData.getData('text');
var regex = new RegExp("^[a-zA-Z.]+$");
var pastedData = window.event.clipboardData.getData('text/plain')
if(pastedData.match(regex) === null) {
event.preventDefault();
return false;
}
});
If you are in fact trying to extend functionality for an HTML tag, you might want to use a directive instead.
To use a factory throughout an application though, it can be done by creating a module for a factory as such:
"use strict";
(function () {
angular.module('example.module.with.factory', [
])
.factory('pasteOptions',function($event) {
var clipboarddata = window.event.clipboardData.getData('text');
var regex = new RegExp("^[a-zA-Z.]+$");
var pastedData = window.event.clipboardData.getData('text/plain')
if(pastedData.match(regex) === null) {
event.preventDefault();
return false;
}
});
})();
and to include this factory into controllers throughout the application, declare it as a parameter in the controllers you wish to use it as such:
"use strict";
(function () {
angular.module("other.module", [
"example.module.with.factory", // Name of the module with the factory
"ui.router"
])
// Include the name of your factory as a parameter to the controller
.controller("otherModule.ctrl", ["$scope", "pasteOptions",
function($scope, pasteOptions) {
// do stuff with your factory
}]);
})();
Related
Short question is: do we need to use var self = this; in a AngularJS Factory and Service?
I have seen AngularJS code for factory or service that uses a var self = this; to remember itself (the service object), and then inside of the functions of the service object, use self to refer to itself. (kind of like how we are afraid we will lose what this is, so we set self = this to use it later, by the principle of closure.
However, I have found that we can safely use this. Why? Because we get back a singleton service object, and when we invoke myService.getNumber(), the this is bound to the service object myService, so it does work. Example:
If it is a service:
https://jsfiddle.net/yx2s3e72/
angular.module("myApp", [])
.service("myService", function() {
console.log("Entering factory");
this.s = "hello";
this.getLength = function() {
return this.s.length;
};
})
.controller("myController", function(myService) {
console.log("Entering controller");
var vm = this;
vm.s = myService.s;
vm.length = myService.getLength();
});
or if it is a factory:
https://jsfiddle.net/935qmy44/
angular.module("myApp", [])
.factory("myService", function() {
console.log("Entering factory");
return {
s: "hello",
getLength: function() {
return this.s.length;
}
};
})
// controller code not repeated here...
It works too. So is it true that we really don't need to set a var self = this; in a custom AngularJS factory or service?
You may lose the reference to this, therefore the reference is saved in the self var.
angular.module('myApp', [])
.run(function (MyService) {
MyService.method();
})
.service('MyService', function ($timeout) {
this.key = 'value';
this.method = function () {
console.log(this) // service
$timeout(function () {
console.log(this); // window because callback is called from the window
}, 0);
}
});
angular.bootstrap(document.querySelector('#app'), ['myApp']);
See JSFiddle
I have two modules and factories in both, and I need to implement factory from the first module into another module.
angular.module('APIs', [])
.value ("myValue" , "12345")
.factory('apiUrl',['config','url',apiUrl])
function apiUrl(config,url){
}
angular.module('users.service', ['APIs'])
.factory('userService',['myValue',userService])
function userService(apiUrl,myValue){
//login function
function login(){
console.log('myValue',myValue)
console.log('loginUrl',apiUrl)
}
return {
login:login
}
}
notice: no problem when I inject myValue, but the problem in APIs Factory
and my log:
Error: [$injector:unpr] http://errors.angularjs.org/1.5.0/$injector/unpr?p0=urlProvider%20%3C-%20url%20%3C-%20apiUrl%20%3C-%20userService
at Error (native)
and sorry for my English.
I would do it like this:
If you create factory use angular.module('app').factory(). If you create service use angular.module('app').service()
Always try to have same module name. It is easier later, when you have big application, because of dependency injection.
Try to keep files separately, and concatenate it later, for example using gulp gulp-concat
Try to keep all you configuration in app.js file and, when you concatenating file, remember, this file should be on top.
I would keep values and constants in app.js file or would create new file like factory or service and include it, same as I injected it below.
app.js
(function () {
'use strict';
var app = angular.module('app', [
// other module
]);
app.value('myValue', '12345');
app.constant('myConst', 'some_constant');
app.config(['$interpolateProvider', function ($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
}]);
}());
factory.js
(function () {
'use strict';
angular
.module('app')
.factory('apiUrlFactory', apiUrlFactory);
apiUrlFactory.$inject = [];
function apiUrlFactory() {
var self = this;
self.url = 'some_url';
return self;
}
}());
service.js
(function () {
'use strict';
angular
.module('app')
.service('userService', userService);
userService.$inject = ['apiUrlFactory', 'myValue'];
function userService(apiUrlFactory, myValue) {
var self = this;
self.login = function () {
console.log('myValue', myValue);
console.log('loginUrl', apiUrlFactory.url);
};
return self;
}
}());
If you have more questions, do not hesitate to contact with me. Also try angular style guide https://github.com/johnpapa/angular-styleguide It will help you a lot.
I am building an app using AngularJs.
I have a function (createStarMarkup) that returns a bunch of HTML based on a number.
function(rating) {
var rating = Number(rating);
var markup = "";
//Do some stuff
return markup;
}
I would like to be able to use this function multiple places in my application, so I defined it as a service in a Utility module.
var app = angular.module('utilities', []);
app.factory('createStarMarkup', function(rating) {
var rating = Number(rating);
var markup = "";
// Do some stuff
return markup;
});
I then add the 'utilities' module as a dependency to one of my other modules, and inject the service into the controller.
var app = angular.module('reviews', ['ionic', 'utilities']);
app.controller('reviewController',
['$scope', '$ionicActionSheet', 'createStarMarkup', function($scope, $ionicActionSheet, createStarMarkup){...});
This produces the following error
Error: [$injector:unpr] Unknown provider: $ratingProvider <- $rating <- createStarMarkup
The error goes away if I remove the rating parameter in the createStarMarkup function. Am I on the right track with using factory or should I look into something else?
Your factory definition is not valid. please change it as follows
app.factory('createStartupServices', ['', function() {
return {
getMarkup: function(rating) {
var rating = Number(rating);
var markup = "";
// Do some stuff
return markup;
},
}
}
]);
And your controller, you need to get the method getMarkup as follows
var app = angular.module('reviews', ['ionic', 'utilities']);
app.controller('reviewController',['$scope', '$ionicActionSheet', 'createStartupServices', function($scope, $ionicActionSheet, createStartupServices){
//createStartupServices.getMarkup(123);
});
The problem is here:
app.factory('createStarMarkup', function(rating) {
You are trying to inject a service called rating, that doesn't exist.
What are you trying to to is this:
app.factory('createStarMarkup', function() {
Service = {};
Service.myFunction = function(rating) {
var rating = Number(rating);
var markup = "";
// Do some stuff
return markup;
}
return Service;
});
In this way you can inject the createStarMarkup in any controller/directive/service and use the function like:
createStarMarkup.myFunction(rating);
I have a code of
var viewerAngular = angular.module('ngAppDemo', ['restangular','btford.socket-io'])
.config(function(RestangularProvider) {
$.get('../config/config.xml',
function(data) {
$(data).find('contentserver').each(function() {
serverDetails.contentserver = assignServerDetails($(this));
var restprovider = RestangularProvider;
restprovider.setBaseUrl("http://"+serverDetails.contentserver.ip+":"+serverDetails.contentserver.port+"\:"+serverDetails.contentserver.port);
//$scope.init();
});
});
I need to invoke function init(), after reading the config(../config/config.xml) file.
I got an error of ReferenceError: $scope is not defined.
How can I add $scope in module.config? Or How can I call function from config?
If you need to add something to every scope in config, you can use $rootScope, but it's better practice to create a service for that data.
You can not ask for instance during configuration phase - you can ask only for providers.
var app = angular.module('app', []);
// configure stuff
app.config(function($routeProvider, $locationProvider) {
// you can inject any provider here
});
// run blocks
app.run(function($rootScope) {
// you can inject any instance here
});
See http://docs.angularjs.org/guide/module for more info.
var viewerAngular = angular.module('ngAppDemo', ['restangular','btford.socket-io'])
.config(function(RestangularProvider) {
$.get('../config/config.xml',
function(data) {
$(data).find('contentserver').each(function() {
serverDetails.contentserver = assignServerDetails($(this));
var restprovider = RestangularProvider;
restprovider.setBaseUrl("http://"+serverDetails.contentserver.ip+":"+serverDetails.contentserver.port+"\:"+serverDetails.contentserver.port);
var Scope=angular.element(document.querySelector('[ng-controller="controllerName"]')).scope();
Scope.init();
});
});
I have a simple question about the dependency injection in Angular. I create custom services in order to use them within each other. Unfortunately I receive errors the way I was trying it. This is my Code:
var myApp = angular.module('app', []);
myApp.service('$service1', ['$rootScope', function($rootScope) {
this.test = function() {
console.log('service1');
};
}]);
myApp.provider('$service2', ['$service1', function($service1) {
var service = 'service2';
this.registerService = function(mytext) {
service = mytext;
};
this.$get = function() {
var that = {};
that.test = function() {
console.log(service);
};
return that;
};
}]);
myApp.config(['$service2Provider', function($service2Provider) {
$service2Provider.registerService('changed service2');
}]);
myApp.controller('AppCtrl', ['$rootScope', '$service1', '$service2',
function($rootScope, $service1, $service2) {
$service1.test();
$service2.test();
}]);
Error: [$injector:modulerr] Failed to instantiate module app due to:
[$injector:unpr] Unknown provider: $service1
http://errors.angularjs.org/1.2.0-rc.2/$injector/unpr?p0=%24service1
If you remove the dependency of $servic1 in $service2 it will work, but why?
The code is mostly right, except you have to inject service dependencies in $get, not in the provider constructor function, like this:
myApp.provider('$service2', function() {
var service = 'service2';
this.registerService = function(mytext) {
service = mytext;
};
this.$get = ['$service1', function($service1) {
var that = {};
that.test = function() {
console.log(service);
};
return that;
}];
});
It appears that provider can not inject such a dependency. If you rewrite $service2 using a factory, it works:
myApp.factory('$service2', ['$service1', function($service1) {
var that = {};
that.test = function() {
$service1.test();
console.log('service2');
};
return that;
}]);
See this plunker: http://plnkr.co/edit/JXViJq?p=preview
Also I believe that service names starting with a $ a reserved for AngularJS and its extensions. Use names without the $ at the beginning for services defined by your application.