Calling angular services globally - angularjs

I have a set of services which represent a backend logic, that is called by different angular controllers.
During development however I want to call these services directly, in order to test them in isolation, from the browser Javascript console.
How this can be done?
Say there is
app.service('service1', function() {
this.sayHello = function() {
return "Hello"
};
});
Now from Javascript console,
app.somethingToGetService('service1').sayHello()
?

You can get injector for module and from it get service:
angular.injector(['ng', 'myApp']).get('service1').sayHello()

Related

How to inject angular service in controller in ionic framework?

I am working on Ionic Framework and there is a requirement that I need to inject the angular services in controller to get the data or perform any CRUD operation in backend. Please Let me know how I can do this?
if you are using Ionic2 here is an example on how to inject a Service into a controller; note the #Injectable decorator in the Service, the [providers] parameter of the #Page decorator in the Controller, and how the service instance is a parameter of the constructor.
Ionic Framework is build upon angular.js, so there s no difference in doing this in Ionic.
Its simple like
var myapp = angular.module('myApp',['ionic']);
myapp.service('MyService',['$http', function($http) {
return {
doSomeThing: function() {
// do something here with $http or whatever
},
doSomeThingElse: function() {
}
}
]);
myapp.controller('MyController',['MyService',function(MyService) {
MyService.doSomeThing();
}]);
In addition to the answer provided by #mJunaidSalaat,
You need to inject IONIC module to angular app module
The remaining implementation will be as it is in Angular
As per below, you can:
angular.module('myApp', ['ionic'])

Can't set angular $scope variable from a callback function in Ionic

I am new in angular js. I am working with web Sql in a test project for learning purpose. My insert operation is working fine. My problem is when i fetch all the records then i can't store it in $scope.todos=results.rows
My code is
tx.transaction(sql,[],myCallback)
function myCallback(tx,results)
{
console.log(results.rows); // shows objects in console
$scope.todos=results.rows;
}
In view the todos is not working with ng-repeat.
It might help to show all of your controller, or service. If it's a controller make sure you included the $scope parameter for example:
.controller('MyController', function ($scope){
}))
If you are doing this inside a service, save it in a variable inside the service, then from a controller where the "$scope" is available include your service then call your variable containing the results. This will also be helpful if you need to share those results with other controllers at a later time.
.service('MyDataService',function(){
var todos;
return {
.... set and get functions to access variable ...
getTodos: function() {
return todos;
}
};
});
And in controller
.controller('MyController', function ($scope, MyDataService){
$scope.todos = MyDataService.getTodos()
}))
There are also ways to get the $scope working in a service but I don't think it's a great idea.

Unavailable Module Error: Overriding an AngularJS Factory with Protractor for E2E testing

I am trying to mock a factory within one of my angularjs modules. The full angularjs application is
angular.module('administration', ['administrationServices'])
The dependency:
var module = angular.module('administrationServices')
contains a factory service:
module.factory('Example', [function(){
return{
list:function(){
return ['This is real']
}
}
}])
This is the service I am attempting to override in my protractor e2e test. The actual test looks something like this:
describe('Example page', function(){
beforeEach(function() {
var mock = function(){
// get the module and provide the mock
var module = angular.module('administrationServices').config(['$provide', function($provide){
$provide.factory('Example',[function(){
return {
list: function(){
return ['This is a Mock Test']
}
}
}])
}])
}
// override the mock service
browser.addMockModule('administrationServices', mock)
})
it('should go to the page and see mock text', function() {
// code that goes to page and checks if the service works
// ...
})
})
The issue I'm having occurs when I $ protractor conf.js, I get the error:
Error while running module script administrationServices: [$injector:nomod] http://errors.angularjs.org/1.3.4/$injector/nomod?p0=administrationServices
This is where I'm confused. Every blog post about protractor's addMockModule uses similar syntax it seems. There are other factory services in administrationServices and those seem to get overwritten because the app can't open to the page due to those services (user and group services) not working.
Anyways, if somebody has seen this and can help direct me in the right direction, that would help; I am fairly new to mock services, protractor and e2e testing.
I think the problem is that your mock function does not return anything. It doesn't share the new module outside the function scope.
var mock = function(){
// get the module and provide the mock
return angular.module('administrationServices').config(['$provide', function($provide){
$provide.factory('Example',[function(){
return {
list: function(){
return ['This is a Mock Test'];
}
}
}])
}])
};
// override the mock service
browser.addMockModule('administrationServices', mock)
Just make it return the new module and it should be fine.

Angular JS - Decorate a service with the controller name

I am unclear of exactly how decorator works in conjunction with the angular $injector, so any explanation is helpful.
Considering my myTempService:
$provide.decorator('myTempService', function($delegate) {
$delegate.controller = // some service to get the current controller
return $delegate;
});
When myTempService is injected into my controller, I need myTempService.controller to be the controller's name:
.controller('MainCtrl', function (myTempService) {
console.log(myTempService.controller); // MainCtrl
});
When you are using .value(), .service(), .factory() and .provider() to register a service, what you pass in as the second parameter will actually be ended up as a part of a Service Provider Constructor.
When an angular's bootstrap process begin, each of those registered service provider constructors will be used to create a Service Provider Instance.
During a Configuration Phase, the service provider instances are available to be injected, and you can use them to change default configuration of to be created service instances.
angular.module('myApp').config(function ($httpProvider) {
// $httpProvider is a provider instance of the $http service
$httpProvider.interceptors.push(function () {});
});
Before entering a Run Phase, each of service provider instance will be used to create a Service Instance.
Then the Decorators will come into play at this point. Before those service instances will be used for injecting to various places, each service instance will be passed into its registered decorators as $delegate parameter if any. The result of the decorator function will be used instead of the
original service instance.
angular.module('myApp').config(function ($provide) {
$provide.decorator('$http', function ($delegate) {
// monkey patching
var originalGet = $delegate.get;
$delegate.get = function () {
console.log('$http.get is called');
return originalGet.apply(this, arguments);
};
return $delegate;
});
});
Therefore, in a decorator function, you have choices to:
Just do something and return the original service instance e.g. print out something for debugging purpose.
Set initial values of the service, that for some reasons cannot be done in a config phase.
Monkey patch the original service instance and return it.
Create and return a wrapper/proxy service over the original service instance.
In unit testing, you could return a mock/spy object instead.
Finally, the service instances will be available for injecting into all of the places e.g. run blocks, controllers, directives, filters etc. for the entire life of the application.

How to retrieve constants for AngularJS from backend

i have some application settings that i want to retrieve from backend, so that they would be available to all of my application controllers via injection. What is the most angular-way to do that?
1) If i only needed settings for one or few controllers i could retrieve them via routing resolve method, but what about global application scope?
2) I could use the .run() method, but since call will be async i have no guaranties that my config will be loaded before i access controllers.
Currently my settings are returned as a json object, and my templates/html files are simply served by web server. So i cannot embed anything into script tags, parse html on the server side or any similar technique.
I would create a service for your settings. Then using the .run() method, called a service that returns your app settings data:
angular
.module('YourApp',[])
.service('Settings',function(){
this.data = {}
})
.run(function(Settings,$http){
$http
.get('/ajax/app/settings')
.success(function(data){
Settings.data = data
})
})
function Controller($scope,Settings){
// use your Settings.data
}
http://docs.angularjs.org/api/angular.Module#methods_run
There is a neat plugin to do the job. https://github.com/philippd/angular-deferred-bootstrap
You need to change bootstrap method
deferredBootstrapper.bootstrap({
element: document.body,
module: 'MyApp',
resolve: {
APP_CONFIG: function ($http) {
return $http.get('/api/demo-config');
}
}
});
angular.module('MyApp', [])
.config(function (APP_CONFIG) {
console.log(APP_CONFIG);
});

Resources