What would be the right (angular-wise) way to load data in the app.config block?
Would a boot module+provider help? i tried the following approach (streamlined) http://jsfiddle.net/Vd5Pg/1/ with no success.
angular.module('boot',[]).provider('test', function(){
this.$get = function() {
return {
getString: function() { return "i am a string"; }
}
};
});
angular.module('main',['boot']).config(['testProvider', function(test) {
//no luck with getString
}]);
The real life situation is that i'd like to load localized routes and determine current language before configuring the $routeProvider.
TIA.
Your current code returns a test service with the method getString. In order to getString() within the provider you should do the below.
angular.module('boot',[]).provider('test', function(){
// Method available in testProvider
this.getString = function () {
return "i am a string";
}
this.$get = function() {
return {
// Your test service.
}
};
});
angular.module('main',['boot']).config(['testProvider', function(test) {
var myString = testProvider.getString();
}]);
Related
I am trying to test an Angular service which I know works functionally as its been in place for a while. I've just come to retro fit some tests around it now but I am getting some strange issue where I get a message "must return a value from $get factory method" from the jasmine test.
The service does work in the website and the service returns an API
var service = {
setStartLanguage: setStartLanguage,
setLanguage: setLanguage,
supportedLanguages: supportedLanguages,
currentLanguage: etCurrentLanguage.currentLanguage,
getLanguage: getLanguage
};
return service;
I believe this is enough to get it working but I can't figure out why the test is complaining about it not returning a $get.
Oh and all I'm doing for the test is trying to expect that the service is defined.
EDIT:
Full service code,
(function () {
'use strict';
angular.module('app.core').factory('etLanguageService', ['$translate', '$route', 'etCurrentLanguage', 'supportedLanguages', 'localStorageService', etLanguageService]);
function etLanguageService($translate, $route, etCurrentLanguage, supportedLanguages, localStorageService) {
function setLanugageFromLocalStorage(storedLanguage) {
etCurrentLanguage.currentLanguage = storedLanguage;
$translate.preferredLanguage(etCurrentLanguage.currentLanguage.code);
localStorageService.set('currentLanguage', etCurrentLanguage.currentLanguage);
}
function setLanguageFromBrowser() {
var language = etCurrentLanguage.get();
if (!language) {
language = '';
}
var cleanLanguage = language.substr(0, 2).toLowerCase();
var supportedLanguage = _.find(supportedLanguages, function(language) {
return language.code === cleanLanguage;
});
$translate.preferredLanguage(supportedLanguage.code);
localStorageService.set('currentLanguage', supportedLanguage);
}
function setStartLanguage() {
// first check if we have a stored language
var storedLanguage = localStorageService.get('currentLanguage');
if (storedLanguage) {
setLanugageFromLocalStorage(storedLanguage);
} else {
setLanguageFromBrowser();
}
}
function setLanguage(language) {
if (etCurrentLanguage.currentLanguage !== language) {
etCurrentLanguage.currentLanguage = language;
$translate.use(etCurrentLanguage.currentLanguage.code).then(function () {
localStorageService.set('currentLanguage', etCurrentLanguage.currentLanguage);
$route.reload();
});
}
}
function getLanguage() {
return localStorageService.get('currentLanguage');
}
var service = {
setStartLanguage: setStartLanguage,
setLanguage: setLanguage,
supportedLanguages: supportedLanguages,
currentLanguage: etCurrentLanguage.currentLanguage,
getLanguage: getLanguage
};
return service;
}
}());
That's hard to tell without more test code.
$get is the method from the provider of your service. For each service, there is a provider which is responsible of creating an instance of your service through the $get method. If you have a service called myService, then there is a provider myServiceProvider. Internaly, when bootstraping your app, Angular calls mysServiceProvider.$get to get an instance of your service.
If you're tinkering with providers and mocks of providers, that could be a reason...
I'm trying to work ui-router with client-side js HtmlService in apps script. After exhaustive tries, I'm stuck with simple js problem
.state('state1', {
url: base+'?page=state1_KB',
views: {
'content':{
template:
function(){
google.script.run.withFailureHandler(notemp).withSuccessHandler(temp).include(obj);
function temp(view){
console.log(view); //This logs successfully.
return view; //This works too I suppose
}
return temp(view); //This doesn't work obviously
},
controller: 'state1Controller'
}
}
})
include(obj) fetches the template and gives it back to temp(view). I need to return the value from temp(view). But obviously it's not gonna return anything.
How to return the outer function after temp(view) has been called by google.script.run?
For pure JS enthusiast, I guess it's quite similar to this:
function outer(){
var a = "b";
setTimeout(function(){console.log("this is Log"); a = 'c';}, 2000);
return a;
}
From ui-router or angular perspective, is there something simpler that I could do to achieve what I'm trying here?
Something like this should work
templateProvider:
function($q){
var deferred = $q.defer();
var temp = function(view){
console.log(view);
deferred.resolve(view);
}
google.script.run
.withFailureHandler(notemp)
.withSuccessHandler(temp)
.include(obj);
return deferred.promise;
},
controller: 'state1Controller'
}
I'm trying to create an angular service which will be visible only in some modules (but not in all). I have tried to create a service in a module and then include it in a different module, but the service is still visible in the entire application.
Example:
var myAppSubModule = angular.module('myAppSubModule',[]);
myAppSubModule.factory('TestSubService', function() {
return {
testFnc: function() {
return 'test';
}
}
});
var myAppModule = angular.module('myAppModule',['myAppSubModule']);
myAppModule.factory('TestService', function(TestSubService) {
return {
testFnc: function() {
return TestSubService.testFnc(); //this should work
}
}
});
var myApp = angular.module('myApp',['myAppModule']);
function MyCtrl($scope, TestSubService, TestService) {
$scope.name = TestService.testFnc(); //this should work
$scope.name2 = TestSubService.testFnc(); //this should fail
}
I want TestSubService to be visible in TestService, but not in the entire application.
Is there any way to achieve this?
I have an AngularJS service. This service uses a $timeout in its function. I'm trying to figure out how to test this service in various situations. Here is my code:
myApp.factory('myService', ['$timeout', function($timeout) {
var isRunning = false;
var myTimer = null;
return {
myTimer: myTimer,
isRunning: isRunning,
execute: function(time) {
this.isRunning = true;
this.myTimer = $timeout(
function() {
this.isRunning= false;
this.myTimer= null;
},
time
);
}
};
}]);
Now, I'm trying to test this code. I have the following written:
describe('myService', function () {
var myService = null;
var $timeout = null;
var $rootScope = null;
beforeEach(inject(function (_$timeout_, _$rootScope_, _myService_) {
myService = _myService_;
$timeout = _$timeout_;
$rootScope = _$rootScope_;
}));
it('should run for one second', function() {
myService.execute(1000);
$timeout.flush();
$rootScope.$digest();
expect(myService.isRunning).toBe(false);
});
});
The test "works". However, if 750 milliseonds have elapsed, I would expect myService.isRunning to be true. However, I do not know how to test for that scenario. Can someone please show me how to test tht situation? thank you
You can imitate a certain amount of time passing with the $timeout.flush method. The method takes an optional parameter called delay. It's explained in the documentation here. With that in mind, you could write a test that looks like this:
it('should run for one second', function() {
myService.execute(1000);
$timeout.flush(750);
$rootScope.$digest();
expect(myService.isRunning).toBe(true);
});
For an app I'm using a skeleton that is very similar to https://github.com/angular/angular-seed.
I've tried something like this, in services.js:
'use strict';
/* Services */
angular.module('mApp.services', []).
factory('$exceptionHandler', function () {
return function (exception, cause) {
alert(exception.message);
}
});
This doesn't do anything, it doesn't seem to overwrite the exceptionHandler.
If I try:
var mod = angular.module('mApp', []);
mod.factory('$exceptionHandler', function() {
return function(exception, cause) {
alert(exception);
};
});
It overwrite the whole app.
How can I properly overwrite the exceptionHandler if I am using a skeleton similar to the default angular app?
It's hard to know for certain without seeing the rest of your app, but I'm guessing angular.module('myApp').factory( ... will work. If you leave out the second parameter (,[]) angular will retrieve an existing module for further configuring. If you keep it angular will create a new module.
try this example
http://jsfiddle.net/STEVER/PYpdM/
var myApp = angular.module('myApp', ['ng']).provider({
$exceptionHandler: function(){
var handler = function(exception, cause) {
alert(exception);
//I need rootScope here
};
this.$get = function() {
return handler;
};
}
});
myApp.controller('MyCtrl', function($scope, $exceptionHandler) {
console.log($exceptionHandler);
throw "Fatal error";
});