Angularjs load module based on conditions - javascript

i am using angularjs and gulp for my application.
here is my directory structure.
content of app.js is
'use strict';
angular.module('BlurAdmin', [
'ngAnimate',
'ui.bootstrap',
'ui.sortable',
'ui.router',
'ngTouch',
'ngRoute',
'ngStorage',
'MyApp.theme',
'MyApp.pages'
]).run(function ($rootScope, $sessionStorage) {
$rootScope.sessionStorage = $sessionStorage;
});
it load page.module.js
content of the page.module.js is
(function () {
'use strict';
var myApp = angular.module('MyApp.pages', [
'ui.router',
])
.config(routeConfig);
/** #ngInject */
function routeConfig($urlRouterProvider, baSidebarServiceProvider) {
$urlRouterProvider.otherwise('/dashboard');
}
var lazyModules = [
'MyApp.pages.dashboard',
'MyApp.pages.create',
'MyApp.pages.otherModule'
];
angular.forEach(lazyModules, function (dependency) {
myApp.requires.push(dependency);
});
})();
This will load all module as menu item in my page. i want to make it conditional based on type of loggedin users.
for that i have used $sessionStorage in .run of app.js, but i am not able to use it in pages.module.js
please help me to load module conditional for example if role is admin then only create module sould be loaded etc..
Thanks.

If i understand correctly you need require.js
Check role and go to page something like "/admin".
$routeProvider.when("/admin", angularAMD.route({
templateUrl: 'your.html', controller: 'createController',
controllerUrl: 'create'
})).when("/other", angularAMD.route({
templateUrl: 'your.html', controller: 'otherController',
controllerUrl: 'other'
}))
https://www.codeproject.com/Articles/808213/Developing-a-Large-Scale-Application-with-a-Single

Try someting like this:
(function () {
'use strict';
var myApp = angular.module('MyApp.pages', [
'ui.router',
])
.config(routeConfig)
.run(lazyModules);
/** #ngInject */
function routeConfig($urlRouterProvider, baSidebarServiceProvider) {
$urlRouterProvider.otherwise('/dashboard');
}
function lazyModules($sessionStorage) {
var userModules = [
'MyApp.pages.dashboard',
'MyApp.pages.otherModule'
];
var adminModules = [
'MyApp.pages.create',
'MyApp.pages.otherModule'
];
var isAdmin = $sessionStorage.admin;
var loadModules = isAdmin ? adminModules : adminModules;
angular.forEach(loadModules, function (dependency) {
myApp.requires.push(dependency);
});
}
})();

Related

Angular Module Config block is never getting called

Angular Config module is not getting invoked.
In the below code snippet, app.state.js is getting invoked, but the config part it's not. Please help me out on this.
This is used in a jhipster application
**app.module.js :**
(function() {
'use strict';
var app= angular
.module('IloadsApp', [
'ngStorage',
'tmh.dynamicLocale',
'pascalprecht.translate',
'ngResource',
'ngCookies',
'ngAria',
'ngCacheBuster',
'ngFileUpload',
'ui.bootstrap',
'ui.bootstrap.datetimepicker',
'ui.router',
'infinite-scroll',
// jhipster-needle-angularjs-add-module JHipster will add new module here
'angular-loading-bar'
]);
app.run(run);
run.$inject = ['stateHandler', 'translationHandler'];
function run(stateHandler, translationHandler) {
stateHandler.initialize();
translationHandler.initialize();
}
})();
**app.state.js :**
(function() {
'use strict';
angular
.module('IloadsApp')
.config(stateConfig);
stateConfig.$inject = ['$statePsrovider'];
alert ("before Inside ");
function stateConfig($stateProvider) {
alert ("Inside ");
$stateProvider.state('app', {
abstract: true,
views: {
'navbar#': {
templateUrl: 'app/navbar/navbar.html',
controller: 'NavbarController',
controllerAs: 'vm'
}
},
resolve: {
authorize: ['Auth',
function (Auth) {
return Auth.authorize();
}
],
translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) {
$translatePartialLoader.addPart('global');
}]
}
});
}
alert("After");
})();

AngularJS unknown provider: $routeProviderProvider

I'm struggling with this unknown provider error and just wondering what I'm doing wrong. Have this structure:
in main.js
'use strict';
angular.module('myApp')
.controller('MainCtrl', ['navService', function (navService) {
this.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
this.active = false;
navService.getPosition();
}]);
In index html I have ng-controller="MainCtrl"
And finally in navService:
angular.module('myApp')
.factory('navService', ['$routeProvider', '$location', function ($routeProvider, $location) {
function getPosition() {
/*code here */
}
return {
getPosition: getPosition
};
}]);
In main app.js
angular
.module('cavyrApp', [
'ngAnimate',
'ngCookies',
'ngMessages',
'ngResource',
'ngRoute',
'ngSanitize',
'ngTouch'
]).config...........
$routeProvider is a provider - you can not inject it into factory/service. You can inject it to the config method only - to configure the service it will provide:
module.config(function($routeProvider) {
// configure the routes here
});
You should inject your factroy like this:
angular.module('myApp',['ngRoute']); //route inject
and the controller:
angular.module('myApp').controller('MainCtrl', function(navService) {
});

angularjs app not working after code concatination

I have and angularjs app.I want to concatenate all the JS files to a single file.I'm currently trying to use Grunt.js to setup an automatic build process for concatenating JavaScript files.
However my app runs without any error before concatenation.But after concatinating the files my app throws Error: $injector:modulerr
Module Error.
Below is my code after minification
angular.module('myApp', []);
var app = angular
.module('myApp', [
'ngRoute'
]);
app.config(function ($routeProvider) {
'use strict';
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'mainCntrl'
})
.when('/about', {
templateUrl: 'views/about.html',
controller: 'aboutCntrl',
controllerAs: 'about'
})
.otherwise({
redirectTo: '/'
});
});
app.controller('mainCntrl',['$scope', function ($scope) {
'use strict';
this.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
}]);
app.controller('aboutCntrl',['$scope', function ($scope) {
'use strict';
this.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
}]);
Any help appreciated.Thanks :)
You need to strictly follow either Inline Array Annotation of DI or $inject Property Annotation while minifying js files.
app.config(function ($routeProvider) {
'use strict';
//code
});
should be changed to below code.
Inline Array Annotation
app.config(['$routeProvider', function ($routeProvider) {
'use strict';
//code as is
}]);
$inject Property Annotation
var config = function($routeProvider) {
'use strict';
//code as is
}
config.$inject = ['$routeProvider'];
app.config(config);
Seems like the config line is your problem, try app.config(['$routeProvider', function ($routeProvider) { ... }]);
Yes, your annotation is not right. It should be
app.config(['$routeProvider', function ($routeProvider) {
'use strict';
//code
}]);
Use ng-annotate as a safe, clean and simple solution.
What it does is that when you grunt it'll annotate your definitions the proper way, so you don't have to deal with Angular's quirky way.
Run ng-annotate on
app.config(function($routeProvider) {
'use strict';
//code
});
and it'll auto-complete it for minification:
app.config(["routeProvider", function($routeProvider) {
'use strict';
//code
}]);
You can also add another step to your build workflow - grunt-ng-annotate in that case you will be able to skip almost all strict DI annotations. With this plugin you can simplify services/controllers definitions e.g.:
app.controller('mainCntrl', function ($scope) {
'use strict';
this.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
});
It is extremely helpful when you heave a long list of services to inject into controller or another service. You don't have to remember to put each dependency twice.

Adding third party vendor dependencies to mean.js

I've been struggling trying to hook up this dependency (http://flowjs.github.io/ng-flow/) to my mean.js application. I'm thinking it's simply a naming problem.
The error I'm getting is: Error: [$injector:unpr] Unknown provider: flowProvider <- flow
I've tried 'flow', 'Flow', 'ngFlow', etc. Any help would be greatly appreciated.
modules/core/client/app/config.js
'use strict';
// Init the application configuration module for AngularJS application
var ApplicationConfiguration = (function() {
// Init module configuration options
var applicationModuleName = 'mean';
var applicationModuleVendorDependencies = ['ngResource', 'ngAnimate', 'ui.router', 'ui.bootstrap', 'ui.utils', 'angularFileUpload', 'flow'];
// Add a new vertical module
var registerModule = function(moduleName, dependencies) {
// Create angular module
angular.module(moduleName, dependencies || []);
// Add the module to the AngularJS configuration file
angular.module(applicationModuleName).requires.push(moduleName);
};
return {
applicationModuleName: applicationModuleName,
applicationModuleVendorDependencies: applicationModuleVendorDependencies,
registerModule: registerModule
};
})();
modules/properties/client/properties.client.controller.js:
'use strict';
var $ = $ || {};
// Properties controller
angular.module('properties').controller('PropertiesController', [
'$scope',
'$stateParams',
'$location',
'Authentication',
'Brands',
'Applications',
'Properties',
'flow',
function($scope, $stateParams, $location, Authentication, Brands, Applications, Properties, flow) {
.......
modules/properties/client/properties.client.module.js:
'use strict';
// Use applicaion configuration module to register a new module
//ApplicationConfiguration.registerModule('properties');
ApplicationConfiguration.registerModule('properties',['flow']);
config/assets/default.js:
'use strict';
module.exports = {
client: {
lib: {
css: [
'public/lib/bootstrap/dist/css/bootstrap.css',
'public/lib/bootstrap/dist/css/bootstrap-theme.css'
],
js: [
'public/lib/angular/angular.js',
'public/lib/angular-resource/angular-resource.js',
'public/lib/angular-animate/angular-animate.js',
'public/lib/angular-ui-router/release/angular-ui-router.js',
'public/lib/angular-ui-utils/ui-utils.js',
'public/lib/angular-bootstrap/ui-bootstrap-tpls.js',
'public/lib/angular-file-upload/angular-file-upload.js',
'public/lib/jquery/dist/jquery.js',
'public/lib/ng-flow/dist/ng-flow-standalone.js'
],
tests: ['public/lib/angular-mocks/angular-mocks.js']
},
css: [
'modules/*/client/css/*.css'
],
less: [
'modules/*/client/less/*.less'
],
sass: [
'modules/*/client/scss/*.scss'
],
js: [
'modules/core/client/app/config.js',
'modules/core/client/app/init.js',
'modules/*/client/*.js',
'modules/*/client/**/*.js'
],
views: ['modules/*/client/views/**/*.html']
},
server: {
allJS: ['gruntfile.js', 'server.js', 'config/**/*.js', 'modules/*/server/**/*.js'],
models: 'modules/*/server/models/**/*.js',
routes: ['modules/*[!core]/server/routes/**/*.js', 'modules/core/server/routes/**/*.js'],
sockets: 'modules/*/server/sockets/**/*.js',
config: 'modules/*/server/config/*.js',
policies: 'modules/*/server/policies/*.js',
views: 'modules/*/server/views/*.html'
}
};
So long as you loaded the js file correctly, you can use flowFactory to create a flow instance. Then create a flow object and use that to refer to flow.
angular.module('properties').controller('PropertiesController', [
'$scope',
'$stateParams',
'$location',
'Authentication',
'Brands',
'Applications',
'Properties',
'flowFactory',
function($scope, $stateParams, $location, Authentication, Brands, Applications, Properties, flowFactory) {
$scope.existingFlowObject = flowFactory.create({
target: 'http://example.com/upload'
});
................................................................
So try changing flow to flowFactory and see if that leads to any provider dependency issues.
I don't see an answer to this. Changing the registerModule part.
ApplicationConfiguration.registerModule('flow');
to .client.module.js
This is mean.js version 0.4.0
you don't have to include it into your project dependency
I modified it in this way :
var applicationModuleVendorDependencies = ['ngResource', 'ngAnimate', 'ui.router', 'ui.bootstrap', 'ui.utils', 'angularFileUpload'];

Angular + Requirejs - how to return multiple modules?

How can I return multiple angular modules in requirejs environment?
this is my app.js,
define([
'angular',
'angular-route',
'jquery'
], function (ng,ngRoute,$) {
'use strict';
console.log($('h1').length);
return ng.module('myApp', ['ngRoute']);
});
And I need a few more modules to return,
ng.module('myAppModule1', ['ngRoute']);
ng.module('myAppModule2', ['ngRoute']);
ng.module('myAppModule3', ['ngRoute']);
a controller example, for instance I want to get 'myAppModule3' in app.js,
define(['app'], function (app) {
var myAppModule = angular.module('myAppModule3');
myAppModule.controller('welcomeController', ['$scope', function($scope) {
//your minsafe controller
$scope.message = "Message from WelcomeController";
}]);
});
You could change app.js to return an object whose fields are the modules:
define([
'angular',
'angular-route',
'jquery'
], function (ng,ngRoute,$) {
'use strict';
console.log($('h1').length);
return {
myApp: ng.module('myApp', ['ngRoute']),
myAppModule1: ng.module('myAppModule1', ['ngRoute']),
myAppModule2: ng.module('myAppModule2', ['ngRoute']),
myAppModule3: ng.module('myAppModule3', ['ngRoute'])
};
});
And change your controller like this:
define(['app'], function (app) {
app.myAppModule3.controller('welcomeController', ['$scope', function($scope) {
//your minsafe controller
$scope.message = "Message from WelcomeController";
}]);
});
The generic (non-Angular specific) way is to use an object:
return {module1: /*..*/, module2: /*...*/ };
Then you just access to the values:
define(['app'], function (app) {
var module1 = app.module1;
});
However in Angular you just registered 'myAppModule1' in the Angular global. There is no need to do the object return, you can retrieve the registered module using the angular object:
define(['angular'], function (angular) {
var module1 = angular.module('myAppModule1');
// without extra parameter it tells angular to retrive an existing
// module
});
Update: I just realize that you did it in your code. It didn't worked? Maybe be you have a dependency issue, make sure that app.js is loaded first.

Categories