Angularjs Provider: is not a function - angularjs

I am trying to configure my Module with a Provider that should allow a custom configuration. This is my Provider:
var module = angular.module('myModule', []);
module.provider('MyModule', function () {
this.setBaseUrl = function (f) {
this.BaseUrl = f;
};
this.setOnForbidden = function (f) {
this.onForbidden = f;
};
this.setOnTokenExpired = function (f) {
this.onTokenExpired = f;
};
this.setOnUnauthenticated = function (f) {
this.onUnauthenticated = f;
};
this.$get = function () {
return this;
};
})
And this is my App that uses the Provider:
angular.module('myApp', ['myModule'])
.config(function (MyModuleProvider) {
MyModuleProvider.setBaseUrl("http://localhost:8080/");
MyModuleProvider.setOnForbidden(
function () {
console.log("Forbidden - User Function");
}
);
MyModuleProvider.setOnTokenExpired(
function () {
console.log("Token Expired - User Function");
}
);
MyModuleProvider.setOnUnauthenticated(
function () {
console.log("User Unauthenticated, wrong username or password - User Function");
}
);
})
The three functions setOnForbidden, setOnTokenExpired and setOnUnauthenticated are working fine alone, but when I add the MyModuleProvider.setBaseUrl("http://localhost:8080/"); it returns the following error:
Failed to instantiate module myApp due to:
TypeError: MyModuleProvider.setBaseUrl is not a function
Why? Is there something wrong in the Provider code?

Related

Error: [$injector:unpr] Unknown provider: musicServiceProvider <- musicService <- MusicController

I have trying to add a service to fetch data from API .
But its gives an error
Error: [$injector:unpr] Unknown provider: musicServiceProvider <-
musicService <- MusicController"
Controller
(function (app) {
var MusicListController = function ($scope, musicService) {
$scope.message = " Jagadish K M";
musicService.getAll().then(function (response) {
$scope.musics = response.data;
console.log($scope.musics);
});
};
app.controller("MusicController", MusicListController);
}(angular.module("theMusic")));
Service
(function (app) {
var musicService = function ($http, musicApiUrl) {
var getAll = function () {
return $http.get(musicApiUrl);
};
var get = function () {
return $http.get(musicApiUrl);
}
var getById = function (id) {
return $http.get(musicApiUrl + id);
};
var update = function (music) {
return $http.put(musicApiUrl + music.id, music);
};
var create = function (music) {
return $http.post(musicApiUrl, music);
};
var destroy = function (id) {
return $http.delete(musicApiUrl + id);
};
return {
getAll: getAll,
getById: getById,
update: update,
create: create,
};
};
app.factory("musicService", musicService);
}(angular.module("theMusic")));
I am newbie in angular. Thanks in advance
You didn't inject your service.
angular.module("theMusic", ["musicService"])
You should take a look to AngularJS Dependency Injection documentation.

AngularJS - Karma testing with providers and injections

I am having a lot of trouble to write the unit test case for a provider that contains some injections.
The particular provider is:
(function () {
angular
.module('core.router', [])
.provider('routerHelper', routerHelperProvider);
routerHelperProvider.$inject = ['$stateProvider', '$urlRouterProvider'];
/**
* This method Initializes the Router Helper provider to be used by all modules
*
* #param $stateProvider
* #param $urlRouterProvider
*/
function routerHelperProvider($stateProvider, $urlRouterProvider) {
this.$get = routerHelperService;
routerHelperService.$inject = ['$state'];
/**
* This method sets the methods to be used by the helper
*
* #param $state
* #returns {Object}
*/
function routerHelperService($state) {
var hasOtherwise = false;
return {
configureStates: configureStates,
getStates: getStates
};
/**
* This method configures all the states to be used by the application
*
* #param {!String[]} states
* #param {!String} otherwisePath
*/
function configureStates(states, otherwisePath) {
states.forEach(function (state) {
//console.log("adding state", state.state, "with config", state.config);
$stateProvider.state(state.state, state.config);
});
if (otherwisePath && !hasOtherwise) {
hasOtherwise = true;
$urlRouterProvider.otherwise(otherwisePath);
}
}
/**
* This method returns the states to be used by the application
*
* #return {Object}
*/
function getStates() {
return $state.get();
}
}
} })();
The basic unit test is:
'use strict';
describe('core.router test', function () {
// All Service injections
var $urlRouterProvider, $stateProvider;
// Mocks
var m_url = function () {
};
var m_state = function () {
};
// Others
var routerHelper, urlRouter, state, base;
// Before statements
beforeEach(module('core.router', function ($provide, _routerHelperProvider_) {
$provide.value('$urlRouterProvider', m_url);
$provide.value('$stateProvider', m_state);
base = _routerHelperProvider_;
}));
// Starting the Factory
beforeEach(inject(function (_routerHelper_, _$urlRouter_, _$state_) {
routerHelper = _routerHelper_;
urlRouter = _$urlRouter_;
state = _$state_;
}));
describe('when testing it', function () {
it('should return true', function () {
//var abc = routerHelper.getStates();
expect(1).toEqual(1);
});
});
});
I keep getting errors like:
Error: [$injector:unpr] Unknown Provider: $stateProvider
Error: [$injector:unpr] Unknown Provider: $urlRouterProvider
Error: [$injector:unpr] Unknown Provider: routerHelperProvider
I tried several different module instantiations and several different injections, but I can't seem to make it work. When I take out the injections ($stateProvider, $urlRouterProvider and $state), the unit test is straightforward.
So, this would be the solution, bringing some complexity because the provider is using both the $state and $stateProvider:
'use strict';
describe('core.router test', function () {
// All Provider injections
var $urlRouterProvider, $stateProvider;
// Mocks
var m_urlProvider = mockDataCore.urlRouterProvider();
var m_stateProvider = mockDataCore.stateProvider();
var m_state = mockDataCore.state();
// Others
var routerHelper, base;
// Define the mock providers
beforeEach(function(){
module(function($provide){
$provide.provider('$urlRouter', m_urlProvider);
$provide.provider('$state', m_stateProvider);
});
});
// Start the module with the internal mock
beforeEach(function () {
module('core.router', function ($provide) {
$provide.value('$state', m_state);
});
});
// Load the provider with module to be able to call its configuration methods
beforeEach(function () {
module(['routerHelperProvider', function (_$urlRouterProvider_, _$stateProvider_, _routerHelperProvider_) {
$urlRouterProvider = _$urlRouterProvider_;
$stateProvider = _$stateProvider_;
base = _routerHelperProvider_;
}]);
});
// Inject and start the provider
beforeEach(function () {
inject(['routerHelper', function (_routerHelper_, $state) {
routerHelper = _routerHelper_;
}]);
});
// test cases
describe('when adding one state and no "otherwise"', function () {
it('otherwise should not be called and state should be saved to state list', function () {
spyOn(m_urlProvider, "otherwise");
spyOn(m_stateProvider, "state");
var simpleState = [{
state : "home",
config : {
url: "/home"
}}];
routerHelper.configureStates(simpleState);
expect(m_urlProvider.otherwise).not.toHaveBeenCalled();
expect(m_stateProvider.state).toHaveBeenCalledWith("home", {url: "/home"});
});
});
describe('when getting the states', function () {
it('should return the states', function () {
spyOn(m_state, "get");
var states = routerHelper.getStates();
expect(m_state.get).toHaveBeenCalled();
});
});
});
The mock methods are:
var mockDataCore = (function () {
return {
urlRouterProvider: urlRouterProvider,
stateProvider: stateProvider,
state: state
};
function urlRouterProvider() {
return {
otherwise: function () { /* void */
},
$get: function () { /* void */
}
};
}
function stateProvider() {
return {
state: function () { /* void */
},
$get: function () { /* void */
}
};
}
function state() {
return {
get: function () {
return {};
},
go: function () { /* void */
}
};
}})();
Of course it doesn't cover all the tests for this provider, but the rest of them are pretty straight forward..

How to use constant in angularjs

How i can use constant in angular, i want to attach a constant value via factory. Please check the following code
/* Factory which attach the constant in app module */
'use strict';
define(['app'], function (app) {
var traslationParams = ['$resource'];
var translationFactory = function (resource) {
return {
attachTranslator: function (language) {
var languageFilePath = applicationUrl.clientUrl + '/translation/translation_' + language + '.json';
resource(languageFilePath).get(function (data) {
app.constant('languagePack', data); // registering constant
});
}
}
}
translationFactory.$inject = traslationParams;
app.factory('translationFactory', translationFactory);
});
// I am executing the factory api to register the constant using following code
app.run([ 'translationFactory', function ( translationFactory) {
translationFactory.attachTranslator('da');}]);
// The usage of constant in controller
var companyController = function (languagePack) {
scope.languagePack = languagePack;
console.log(languagePack);
}
but i am getting an error in my controller
Error: [$injector:unpr] Unknown provider: languagePackProvider <- languagePack <- companyController
Add languagepack as a translationFactory attribute and save the translation output to this attribute. Further reference this attribute through service in the controller.
'use strict';
define(['app'], function (app) {
var traslationParams = ['$resource'];
var translationFactory = function (resource) {
return {
languagePack: {},
attachTranslator: function (language) {
var trans = this;
var languageFilePath = applicationUrl.clientUrl + '/translation/translation_' + language + '.json';
resource(languageFilePath).get(function (data) {
//app.constant('languagePack', data); // registering constant
trans.languagePack = data
});
}
}
}
translationFactory.$inject = traslationParams;
app.factory('translationFactory', translationFactory);
});
app.run([ 'translationFactory', function ( translationFactory) {
translationFactory.attachTranslator('da');}]);
var companyController = function (translationFactory) {
scope.languagePack = translationFactory.languagePack;
console.log(scope.languagePack);
}

Angular: Using $http in a provider

I've created an angular Provider which is exposing a getSession method which I need to resolve before going into a specific route:
var serviceId = 'session';
angular.module("app").provider(serviceId, sessionProvider);
function sessionProvider() {
this.session = undefined;
this.$get = function($http) {
return {
getSession: function () {
return $http.get("/session-info")
.then(_onSuccess, _onError);
}
}
}
function _onSuccess(data) {
return data.data;
}
function _onError(data) {
return data;
}
}
I then inject it into my config and try to use it:
angular.module("app").config([
"$routeProvider", "$httpProvider", "sessionProvider", function
($routeProvider, $httpProvider, sessionProvider) {
$routeProvider.when("/", {
templateUrl: "app/home/home.html",
resolve: {
session: sessionProvider.getSession()
}
});
}
]);
But I get the following error:
Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to:
TypeError: undefined is not a function
I'm not sure what I've done wrong here?
Edit
When I try #DrogoNevets answer below:
function sessionProvider() {
this.session = undefined;
this.$get = function ($http) {
return {
}
}
this.getSession = function () {
return $http.get("/session-info")
.then(_onSuccess, _onError);
}
function _onSuccess(data) {
this.session = data.data;
return data.data;
}
function _onError(data) {
return data;
}
}
I get the following error as I'm not able to inject $http into the provider itself, is that correct?
Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to:
ReferenceError: $http is not defined
if you want to call getSession from the config part you need to assign it to this not within the $get part
try something like this:
function sessionProvider() {
var session;
this.$get = function() {
return {
getSession: this.getSession,
setSession: this.setSession
}
}
function _onSuccess(data) {
return data.data;
}
function _onError(data) {
return data;
}
this.getSession= function () {
return session
}
this.setSession= function (id) {
session = id;
}
}
here is a fiddle showing what I mean: http://jsfiddle.net/EQ86N/1/

Failed to instantiate module ng due to: Error: [$injector:unpr] http://errors.angularjs.org/undefined/$injector/unpr?p0=%24logProvider

I create this to decorate the $log:
window.fofr = window.fofr || {};
window.fofr.library = window.fofr.library || {};
window.fofr.library.logging = window.fofr.library.logging || {};
window.fofr.library.logging.errorLogViewerService = function () {
var configure = function (angularJsModule) {
angularJsModule.config(function ($provide) {
$provide.decorator('$log', function ($delegate, $sniffer) {
var _error = $delegate.error; // Saving original function
var _log = $delegate.log;
$delegate.logs = [];
$delegate.error = function (msg) {
_error(msg);
};
$delegate.log = function (msg) {
_log(msg);
$delegate.logs.push(msg);
};
return $delegate;
});
});
};
return {
configure: configure
};
} ();
I create a unit test with qunit:
module('Library - Logging - ErrorLogViewer', {
setup: function () {
this.app = angular.module('app', []);
}
});
test('Log - check the logs is filled with log', function () {
window.fofr.library.logging.errorLogViewerService.configure(this.app);
var injector = angular.injector(['app', 'ng']);
injector.invoke(function ($log) {
$log.log('test');
equal($log.hasOwnProperty('logs'), true, 'The property logs must exists');
equal($log.logs.length, 1, 'The logs must contain one log');
});
});
But it crash in the config saying that it doesn't know the logProvider???
ok, I found, the $log is defined in ng module, angular search in module defined by the order set in the code : angular.injector(['app', 'ng']);
so I set this angular.injector(['ng', 'app']); and now it works!

Resources