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

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.

Related

Angular component does not render template

Based on a tutorial from UI-Router
(https://ui-router.github.io/ng1/tutorial/hellogalaxy) I have these states in my Angular app:
angular
.module('appRoutes', ["ui.router"])
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
// An array of state definitions
var states = [
{ name: 'home', url: '/', component: 'home' },
{ name: 'about', url: '/about', component: 'about' },
]
// Loop over the state definitions and register them
states.forEach(function(state) {
console.log(state.component)
$stateProvider.state(state);
});
$urlRouterProvider.otherwise('/');
}]);
Here is my other file that contain module declaration:
'use strict';
var talentforceApp = angular.module("talentforce", []);
angular
.module('TalentForce_Application', [
'appRoutes',
'talentforce',
'ngResource'
]);
And the file for one of those simple components:
talentforceApp.component('about', {
template: '<h3>About TalentForce</h3>'
})
When I run it, my console gives no errors. I checked and the state and component is indeed saved. It just doesn't render. When I click the About button of my app, there is no template, just blank and no errors. It is hard to debug since there are no errors. What am I missing here?
angular.module('appRoutes').component('about', {
template: '<h3>Template</h3>'
})
You have most likely found a solution for this but here it goes anyway.
In the example, all components are part of the same angular module ('hello') whereas you have added to components into a separate module.
You need to add TalentForce_Application as a dependency to your main module appRoutes.
angular
.module('appRoutes', ["ui.router", "talentforce"])
...

Using ocLazyLoad to lazy load a controller with $stateProvider

I'm having issues using oclazyload with $stateProvider.
I have specified that the controller .js should be loaded in the router config, and it does,' but it's not available to use as an ng-controller attribute in the file loaded in templateURL.
ui-route config:
core
.run(
[ '$rootScope', '$state', '$stateParams',
function ($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
}
]
)
.config(
[ '$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
console.info('Routing ...');
$urlRouterProvider
.otherwise('/app/dashboard');
$stateProvider
.state('app', {
abstract: true,
url: '/app',
templateUrl: 'templates/app.html',
})
.state('app.orders', {
abstract: true,
url: '/orders',
templateUrl: 'templates/orders/orders.html',
})
.state('app.orders.index', {
url: '/index',
templateUrl: 'templates/orders/index.html',
resolve: {
deps: ['$ocLazyLoad',
function( $ocLazyLoad ){
console.info('Path ot order controller in route config',Momento.paths.js + 'controllers/orders/index.js');
return $ocLazyLoad.load([
Momento.paths.js + 'controllers/orders/index.js'
])
}
]
}
})
}
]
)
;
And my templateURL file starts:
<div class="" id="" ng-controller="OrdersIndexController">...</div>
But when it loads, console throws the error:
<info>orders/index controller loaded controllers/orders/index.js:3
<info>Now I've finished loading the controller/order/index.js config/ui-router.js:69
<info>orders template loaded VM30437:1 (<-- this is the app.orders abstract template with ui-view directive ready for app.orders.index view)
<error>Error: [ng:areq] Argument 'OrdersIndexController' is not a function, got undefined
... <trace>
So the file is loaded correctly by lazyload, confirmed by console output above and network tab in developer tools, but it's not available in the templateURL to use as controller? Does it need to be aliased either in router config using controller:'' key or in template? Does it need to be specifically attached to the (only) module in this app?
What am I missing?
PS: confirming that the name of the controller is in fact OrdersIndexController:
core
.controller('OrdersIndexController', [
'Model', '$scope', '$window',
function( Model, $scope, $window){
console.info("OrdersIndexController fired");
}
]);
You have to register your controller with
angular.module("myApp").controller
Working
angular.module("myApp").controller('HomePageController', ['$scope', function ($scope) {
console.log("HomePageController loaded");
}]);
Not working
var myApp = angular.module("myApp")
myApp.controller('HomePageController', ['$scope', function ($scope) {
console.log("HomePageController loaded");
}]);
Inside the function function($ocLazyLoad){} you must to declare the name of module that contains the controller and the name of file "to lazy load"
function( $ocLazyLoad ){
return $ocLazyLoad.load(
{
name: 'module.name',
files: ['files']
}
);
}
If you use the current documented way for ocLazyLoad 1.0 -> With your router
...
resolve: { // Any property in resolve should return a promise and is executed before the view is loaded
loadMyCtrl: ['$ocLazyLoad', function($ocLazyLoad) {
// you can lazy load files for an existing module
return $ocLazyLoad.load('js/AppCtrl.js');
}]
}
then in js/AppCtrl.js
You have something like this:
angular.module("myApp").controller('DynamicNew1Ctrl', ['$scope', function($scope) {
$scope.name = "Scoped variable";
console.log("Controller Initialized");
}]);
Note that with angular.module("myApp") you are attaching the new controller to an existing module, in this case the mainApp, so any of new dynamic controllers can use the app dependencies.
but you can define a new module an inject your dependencies, as described here, the later is used commonly when you estructure your app with a plugin architecture and you want to isolate the dynamic modules so they only have access to some especific dependencies

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

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

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'
});
}]);

AngularJS - Getting Module constants from a controller

I'm trying to build a myApp.config module to store some settings for my app, I wrote a config.js file:
angular.module('myApp.config', [])
.constant('APP_NAME','My Angular App!')
.constant('APP_VERSION','0.3');
I added it to my app.js (angular-seed):
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'myApp.controllers', 'myApp.config']).
I added it to the index.html file, and now I'm trying to figure out how to get it in my controllers, I tried:
angular.module('myApp.controllers', ['myApp.config'])
.controller('ListCtrl', ['$scope', 'myApp.config', function($scope, $config) {
$scope.printme = $config;
}])
but I'm getting:
Unknown provider: myApp.configProvider <- myApp.config
I'm probably doing something wrong here, any ideas ?
I don't think it is valid to use the module name in an injection like that. You can simply inject the constants by name, though:
angular.module('myApp.controllers', ['myApp.config'])
.controller('ListCtrl', ['$scope', 'APP_NAME', function($scope, appName) {
$scope.printme = appName;
}]);
I think the simplest approach is to add a constant using an object literal. This fits most application configuration use cases I think, because it supports a complex config object. The constant step also runs early, before other providers are registered.
angular.module('myApp').constant('cfg', {
url: 'https://myapi.com/v1/',
httpTimeout: 5000
})
To use it you just inject cfg:
angular.module('myApp').factory('user', function(cfg, $http){
// cfg and $http together at last
})
It should also be noted that SimplGy's solution means that the 'cfg' object is a constant, however the properties of that object are not. This means, that you cannot reassign 'cfg' like so:
cfg = { randomProperty: randomValue };
You CAN reassign the properties of the 'cfg' object like so:
cfg.url = 'BrandNewURL.com';
cfg.httpTimeout = 30;
Check out the use of constants in this example:
angular
.module('abp001App', ['ngRoute'])
.constant("myConfig", {
"url": "http://localhost",
"port": "80"
})
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.otherwise({
redirectTo: '/'
});
})
.controller('MainCtrl', function (myConfig) {
// Do something with myConfig...
});

Categories