AngularJS why can't I use share a provider with another module? - javascript

I have a App module that has many component modules that are injected into the App module. The App module has a provider that I would like to use inside of the component modules, but I am receiving an injector error: Error: $injector:modulerr Module Error
Here is what I am trying
var App = angular.module('App', [
'ngRoute',
'Blog',
'Media',
'Pages',
]);
App.provider('Core', function() {
this.baseDirectory = '/test';
this.$get = function() {
var baseDirectory = this.baseDirectory;
}
});
App.config(['$routeProvider', 'CoreProvider', function($routeProvider, CoreProvider) {
$routeProvider
.when(CoreProvider.baseDirectory + '/admin', {
templateUrl: baseUrl + '/backend/scripts/angular/index.html'
})
.otherwise({
template: ""
});
}]);
All of the above code works, its when I try to use the CoreProvider inside of another module, such as Blog (has been injected into App module)
var Blog = angular.module('Blog', ['ngRoute']);
Blog.config(['$routeProvider', 'CoreProvider', function($routeProvider, CoreProvider) {
$routeProvider
.when(CoreProvider.baseDirectory + '/admin/blog', {
templateUrl: CoreProvider.baseDirectory + '/blog/blog.html',
controller: 'BlogController'
});
}]);
I receive the error Error: $injector:modulerr Module Error and the Angular docs state that this error occurs when a module fails to load due to an exception.
Why can't I use CoreProvider inside of my Blog module?

If sharing a base directory is all you need, why not use a Constant?
var shared = angular.module('Shared',[]);
shared.constant('baseDirectory', '/test');
// Use the constant on your modules:
var module1 = angular.module('Module1', ['Shared']);
module1 .config(['baseDirectory', function(baseDirectory) {
console.log(baseDirectory + '/admin2');
}]);
var module2 = angular.module('Module2', ['Shared']);
module2.config(['baseDirectory', function(baseDirectory) {
console.log(baseDirectory + '/admina');
}]);
Here is a working plunkr: http://plnkr.co/edit/wktdqCMZuvDbk7sz1mMi?p=preview
I guess that this is a better practice, for more info please refer to: https://docs.angularjs.org/guide/providers

Related

Link module from external file in AngularJS

I'm working on new project and I want to use two modules placed in separated files. Unfortunetaly, when I try to declare second in my root one I receive an error
Uncaught Error: [$injector:modulerr]
So, here is my root file, app.js:
var beerMe = angular.module("beerMe", ["admin", "ngRoute"])
.config(["$routeProvider", function($routeProvider) {
$routeProvider
.when("/home", {
templateUrl: "../views/home/home.html",
controller: "MyCtrl"
})
.otherwise({
redirectTo: "/home"
})
}])
.controller("MyCtrl", ["$scope", function($scope) {
}]);
And second one, which I want to bind, admin.js:
var admin = angular.module("admin", ["firebase", "ngRoute"]);
admin.config(["$routeProvider", function($routeProvider) {
$routeProvider
.when("/", {
templateUrl: "views/add.html",
controller: "AdminCtrl"
}).when ("/edit", {
templateUrl: "views/edit.html",
controller: "AdminCtrl"
}).otherwise({
redirectTo: "/"
})
}]);
admin.controller("AdminCtrl", ["$scope", "$firebaseArray", function($scope, $firebaseArray) {
// my code goes here
}]);
In admin.js I connnect to firebase and I want to have access to all data from my module "beerMe".
I'd be very grateful if you could help me to figure out why there's a problem with binding these two.
Change var admin = angular.module("admin", ["firebase", "ngRoute"]);
to var admin = angular.module("admin");
and change root module like this
var beerMe = angular.module("beerMe", ["admin", "ngRoute", "firebase"])
It looks like your dependencies are the wrong way round. Having admin as a dependency of beerMe will not make the beerMe module available in your admin module.
If you want your admin module to be able to access data from inside the beerMe module then beerMe should be a dependency of admin.
var admin = angular.module('admin', ['firebase', 'ngRoute', 'beerMe']);

how to call a ui-router state declared in another angular module

I have created two angularjs module of the same application. How can I call from the module A the state x declared in the module B? Do you have any idea or workaround?
when I call the state x in this way
$state.go('x')
from the module A, it isn't found
// This is your parent module
var app = angular.module('app', [
'ui.router',
// Application modules
'moduleA',
'moduleB'
]);
// This is your child module 1
var moduleA = angular.module('moduleA', ['ui.router']);
moduleA.config(['$stateProvider', function($stateProvider) {
$stateProvider
.state('moduleA', {
url: '/route1',
controller: 'moduleAController',
template: "<div>Test</div>"
});
}]);
// This is your child module 2
var moduleB = angular.module('moduleB', ['ui.router']);
moduleB.config(['$stateProvider', function($stateProvider) {
$stateProvider
.state('moduleB', {
url: '/route2',
controller: 'moduleBController',
template: "<div>Test</div>"
});
}]);
Explanation - With this you have one parent module with 2 child modules. Child modules services, controllers and directives can be used across these 3 modules without any dependency injection.

"Cannot read property 'untilResolved' of undefined" in angular-route-segment?

I am setting up a simple routing configuration with angular-route-segment and Angular is throwing this error on app load:
TypeError: Cannot read property 'untilResolved' of undefined
Neither Angular nor angular-route-segment provide anything more helpful in the way of error messages.
app.js:
(function () {
'use strict';
var app = angular.module('emailHandlerApp', [
// Angular modules
'ngAnimate', // animations
'ngRoute', // routing
'ngSanitize', // sanitizes html bindings (ex: topnav.js)
// 3rd Party Modules
'ui.bootstrap', // ui-bootstrap (ex: carousel, pagination, dialog)
'route-segment', // angular-route-segment
'view-segment', // angular-route-segment
]);
console.log("app loaded"); // just for debug!
})();
config.route.js:
(function () {
'use strict';
var app = angular.module('emailHandlerApp');
// Configure the routes and route resolvers
app.config(function ($routeSegmentProvider, $routeProvider) {
$routeSegmentProvider.options.autoLoadTemplates = true;
$routeSegmentProvider.options.strictMode = true;
$routeSegmentProvider
.when('/', 'emailHandler')
.when('/unsubscribe', 'emailHandler.unsubscribe')
.when('/redirect', 'emailHandler.redirect')
// Base shell
.segment('emailHandle', {
templateUrl: 'app/shell.html',
controller: 'baseController',
controllerAs: 'vm',
})
.within()
// Dashboard
.segment('unsubscribe', {
templateUrl: 'app/unsubscribe/unsubscribe.html',
controller: 'unsubscribeController',
controllerAs: 'vm',
dependencies: ['emailId']
})
// Recruiting
.segment('redirect', {
templateUrl: 'app/redirect/redirect.html',
controller: 'redirectController',
controllerAs: 'vm',
dependencies: ['rdId']
})
;
$routeProvider.otherwise({ redirectTo: '/' });
})
})();
Answering my own question because I'm 99% sure I'll probably Google this again a month from now.
This one is super simple - just a matter of code blindness and a slightly uninformative error message. angular-route-segment throws this when there's a name out of place somewhere in your segment tree.
In my case, I had mistyped .segment('emailHandle', { ... }) when I meant emailHandler, and then it barfed once it hit the .within(). I felt pretty dumb once I saw it.

Injecting services/constants into provider in Angularjs

The problem here is I am able to access the getRoutes(), but I am unable to access the injected constant -"configuration". What am I missing? Thanks.
(function () {
'use strict';
var app = angular.module('app');
app.constant('configuration', {
PARTIAL_PATH: "/app/components/partials"
});
app.module('app', [
'routeService'
]);
var routeServiceModule = angular.module('routeService', ['common']);
routeServiceModule.provider('routeConfig',function () {
this.getRoutes = function () {
return [
{
url: '/login',
config: {
title: 'admin',
templateUrl: 'app/components/login/login.html'
}
}, {
url: '/',
config: {
templateUrl: 'app/components/dashboard/dashboard.html',
title: 'Dashboard'
}
}
];
};
this.$get = ['configuration', function (configuration) {
var service = {
getRoutes: getRoutes(),
configuration: configuration.PARTIAL_PATH
};
return service;
}];
app.config(['$routeProvider', 'routeConfigProvider', function ($routeProvider, routeConfigProvider) {
//Unable to get the configuration value
console.log(routeConfigProvider.configuration);
//Console is returning as "undefined"
routeConfigProvider.getRoutes().forEach(function(r) {
$routeProvider.when(r.url, r.config);
});
$routeProvider.otherwise({ redirectTo: '/' });
}
]);
})();
Created a plunkr demo : http://plnkr.co/edit/2TIqgxMxBJEPbnk2Wk6D?p=preview
(Regarding your last comment, with the plnkr)
The result is expected.
At config time (within app.config() ), you access raw providers, as you defined them, which allows you to call "private" methods or fields (testItem1) and to configure it for run time use. "private" because they won't be accessible at run time.
At run time (within app.run() and the rest of your app), when you ask for a dependency for which you wrote a provider, the angular injector hands you the result of the $get method of your provider, not the provider itself, so you can't access the "private" function.
This page was my path to enlightenment : AngularJS: Service vs provider vs factory
I think you may be over complicating the route stuff. You may have a very good reason for it but as I do not know it may I suggest keeping it simple with something more like this:
MyApp.config(function ($routeProvider) {
$routeProvider.when('/home', {
templateUrl: 'home.html',
controller: 'HomeController',
activeTab: 'home'
})
};
MyApp.controller('HomeController', function ($route) {
console.log($route.current.activeTab);
});
I would be interested in knowing why you may not able to use this routing pattern or purposely chose something different.
I think it has to do with the way you are creating your initial module. Try this:
var app = angular.module('app', []);
app.constant('configuration', {
PARTIAL_PATH: "/app/components/partials"
});
var routeServiceModule = angular.module('routeService', ['app']);

AngularJS - Uncaught Error: Service name expected from myApp

I'm trying to implement a Facebook provider (angular-facebook.js) as show in the below plnkr:
http://plnkr.co/edit/dDAmvdCibv46ULfgKCd3?p=preview
However, I've made a bit of a hash with my config files. The plnkr example doesn't use a route provider so I'm unsure how to structure my .config to both utilize the route provider and initialize my Facebook implementation:
Current but Not Working
'use strict';
var myApp = angular.module('myApp ', ['facebook'])
.config(
['FacebookProvider',
function(FacebookProvider){
var myAppId = '4605923966';
FacebookProvider.init(myAppId);
},
function($routeProvider)
{
$routeProvider.when('/admin/area',
{
templateUrl: 'app/admin/area/index.html'
});
}]
);
The method config only takes one function as a parameter, so you need to inject both FacebookProvider and $routeProvider into it like this:
'use strict';
var myApp = angular.module('myApp ', ['facebook'])
.config(['FacebookProvider', '$routeProvider',
function(FacebookProvider, $routeProvider) {
var myAppId = '4605923966';
FacebookProvider.init(myAppId);
$routeProvider.when('/admin/area', {
templateUrl: 'app/admin/area/index.html'
});
}]);

Categories