concatenate javascript in anonymous function with gulp - javascript

I use gulp to concat my scripts into one file. Before concatenation I've split up my .js files into seperate files.
So I've got app.js where I declare my angular app and some other stuff. But I've also got route.js where I declare my routing. However, the declaration of my angular app in app.js is wrapped inside an anonymous function, so when it concatenates app.js and route.js, route.js falls outside the scope of the declaration of my Angular app.
Is there some way to inject a script into the scope with Gulp in stead of concatenate it all together? Or is there some other approach I'm missing, apart from didging JSLint and the anonymous function?

If you're not using CommonJS or AMD modules and just concatenating scripts then just make sure each concatenated script gets the module it needs in it's own scope.
(function() {
// Declare app
var app = angular.module('Application', ['ngRoute']);
// Do stuff with variable app in scope.
})();
Now in your routes.js
(function() {
// Grab the already created module for use
// in this scope.
var app = angular.module('Application');
app.config([
'$locationProvider',
'$routeProvider',
function($locationProvider, $routeProvider) {
$locationProvider.html5Mode = true;
$routeProvider.when('/', {
controller : 'MyCtrl',
templateUrl : 'index.html'
});
}
]);
})()

Related

AngularJS undefined Controller using require

I am using requireJS in my application.
Whenever i tried to register controller on my module it said that the controller is not defined. Here is my controller which resides on login.controller.js
function LoginController() {
}
and here's my module code:
require('angular')
require('#uirouter/angularjs');
require('./service/storage')
require('./controller/login.controller')
angular.module('SecurityModule', ['ui.router'])
.controller('LoginController', LoginController);
// Routing
angular.module('SecurityModule')
.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.hashPrefix('');
$stateProvider.state('login', {
url: '/login',
templateUrl: '/app/resources/view/security/login.html',
controller: 'LoginController',
});
})
;
When i checked my bundled.js the declaration of LoginController appears first. So why is it still undefine?
Thanks.
NOTE that im using browserify (which then uses commonJS) to bundle my files.
As the documentation states:
A module is a collection of configuration and run blocks which get
applied to the application during the bootstrap process. In its
simplest form the module consist of collection of two kinds of blocks:
Configuration blocks - get executed during the provider registrations
and configuration phase. Only providers and constants can be injected
into configuration blocks. This is to prevent accidental instantiation
of services before they have been fully configured.
angular.module('myModule', []).
config(function(injectables) { // provider-injector
// This is an example of config block.
// You can have as many of these as you want.
// You can only inject Providers (not instances)
// into config blocks.
}).
run(function(injectables) { // instance-injector
// This is an example of a run block.
// You can have as many of these as you want.
// You can only inject instances (not Providers)
// into run blocks
});

Why is my Angularjs Service not allowing me to call it?

I'm trying to make an Angular Service that houses common functions.
I bundled the code within my MVC app:
bundles.Add(new ScriptBundle("~/bundles/Angular")
.IncludeDirectory("~/app", "*.js", true));
And I checked in Developer Tools if it actually brought in my Common Folder with Common.js :
I added Common to the App :
var app = angular.module('app',
[
'JobCtrl',
'JobSvc',
'WebsiteCtrl',
'WebsiteSvc',
'myClientCtrl',
'ClientSvc',
'MediaCompanyCtrl',
'MediaCompanySvc',
'PageAlertSvc',
'ui.bootstrap',
'ui.bootstrap.tpls',
'Common'
]
);
and to the Controller:
angular.module('app', ['ui.bootstrap', 'ui.bootstrap.tpls'])
.controller('JobCtrl',
[
'JobService',
'WebsiteService',
'MediaCompanyService',
'ProductService',
'$scope',
'$uibModal',
'PageAlertService',
'Common',
function (JobService, WebsiteService, MediaCompanyService,
ProductService, $scope, $uibModal,PageAlertService, Common)
This is what my Common.js file looks like:
angular.module('app')
.service('Common', function () {
this.heyThere = function ()
{
console.log('Just wanted to say hey there')
};
});
Whenever it is called within my JobCtrl I get a Error: $injector:unpr
Unknown Provider.
Could anyone see what I may be doing wrong where it won't recognize my Common.js file? When I move Common.js to the Services folder and try calling it within my controller it works, but not when it is in my Common Folder. Makes no sense!
Thanks in advance!
That is simply because you are defining your app..twice!!!!
angular.module('app', []) // this is where you re-define your app
.service('Common', function () {
this.heyThere = function ()
{
console.log('Just wanted to say hey there')
};
});
should be:
angular.module('app')
.service('Common', function () {
this.heyThere = function ()
{
console.log('Just wanted to say hey there')
};
});
the module function has 2 modes.. with 2 arguments you are setting up your app.. with a single argument you just getting a reference to an existing app (which is already defined before that)
Please be careful when you use the declaration of a module. You are basically reassigning the app module to different instances.
angular.module('app', [dependencies]) //Constructs a module with dependencies
angular.module('app').service(...) //Associates the components (service)
//with the app module.

How to separate controllers in different files for angularjs?

I have a globale routes controller and want to create an additional controller for each page template.
It's done as follows:
var app = angular.module('myapp', ['ngSanitize', 'ngRoute']);
app.config(function($routeProvider){
$routeProvider
.when("/test", {
templateUrl: "./templates/test.html",
controller: "testController"
})
});
app.controller('test', function() {
//...
});
Question: how can I move the controller to it's own testController.js file? I tried it, but then the controller does not work anymore.
Which steps do I have to take if I extract the controller in its own file?
How can I get access to var app module variable from within testController.js?
Do I necessairly have to include each controller as new <script src="js/testController.js"></script> tag entry in my html templates? That would be cumbersome, as I want to split my application into many controllers, and that would result in many many imports.
You can access app by simply declaring it without dependencies:
var app = angular.module('myapp');
app.controller("testController", function() {
});
And yes, you need to include testController.js on every page that needs it.

Retrieving Constants\string values from a separate JS File

I am developing an Angular JS application.
I would like to know what is the best practice to include string values in our code.
I am planning to use another JS File which contains all the constant values. I will call this JS file in each and every JS(Controller) to refer the string values.
You can define constants in angular like
angular.module('moduleName',[]).constant('constName',string|object|array);
You can inject in directive or controller or wherever you want.
angular.module('moduleName',[]).directive('directiveName', ['constName', function(constName){...});
You have several options.
Global value. You can use your constants in form of the javascript object which would be globally accessible across the application. For example, your file could look something like this:
config = {
host: 'domain',
port: '1234'
};
Obvious disadvantage is that those values are not really a constants and can be easily changed, so it's error prone.
Angular config module. More reliable and cleaner option is to create a separate module to be used as a dependency for main app module. You would still have separate file for your constants but instead of some global variable this file would hold angular module with constant service. Something like this:
angular.module('app.config', []).constant('config', {
host: 'domain',
port: '1234'
});
Then in main application you would configure app like
angular.module('app', ['app.config']).config(function(config) {
// console.log(config);
});
Here is the sample code;
var app = angular.module('plunker', []);
app.constant('configs', {host:'localhost',port:8080});
app.controller('MainCtrl', function($scope, configs) {
$scope.name = configs.host;
});
here is demo plunker
Angular has a built in way of providing constants, e.g:
angular.module('foo', ['ngRoute']) // Your angularjs module
// Decide a name for the bucket of constants, then just declare the
// constants in turn as an object literal:
.constant("HTTP_CONSTANTS", {
"URL": "http://localhost",
"PORT": "80"
})
Then you can load it anywhere where you have access too you foo module using dependency injection, i.e.:
angular.module('foo')
.controller('bar', function (HTTP_CONSTANTS) {
... // Use HTTP_CONSTANTS.URL or HTTP_CONSTANTS.PORT, for example
})
Here's a good primer on using constants:
http://twofuckingdevelopers.com/2014/06/angularjs-best-practices-001-constants/
You can use factory for this purpose and inject this factory where ever you want these constants.
var app=angular.module('Myapp', []);
app.factory('ConstantService', function(){
var constant={temp:'c'};
var getConstants=function(){
return constant;
};
return{
constants:getConstants;
}
});
app.controller('MyController',['ConstantService' function (ConstantService){
var constant= ConstantService.constants;
}]);

angular force me to make variables on window

I want to follow angularjs recommendation (http://docs.angularjs.org/guide/module):
While the example above is simple, it will not scale to large
applications. Instead we recommend that you break your application to
multiple modules like this:
A service module, for service declaration A directive module, for
directive declaration A filter module, for filter declaration And an
application level module which depends on the above modules, and which
has initialization code.
So I've created services.js file that only contains:
window.myservices = angular.module('services', []);
And then I added a few services where each service file starts with:
window.myservices.factory('service1', function() {
....
});
I made the same for filters.js and directives.js.
In my app.js file I made:
window.App = angular.module('app', ['services', 'filters', 'directives']).
// run \ config \ whatever
How can I do it without making variables on window?
There's no need for globals at all:
// Define your services
angular.module('services', [])
.factory('service1', function(){})
.factory('service2', function(){});
// Define you main app module and specify the dependencies
angular.module('MyApp', ['services']);
As Stewie said, you can use angular.modue('service',[]);
However you only need to do this in the first loaded file, like so:
file1.js
var mod = angular.module('service',['dependancy']);
file2.js
var mod = angular.module('service');
index.html
<script src="/scripts/file1.js"></script>
<script src="/scripts/file2.js"></script>
Another option is to use namespaces...
file1.js
var mod = angular.module('service.part1',[]);
file2.js
var mod = angular.module('service.part2',[]);
main.js
var mod = angular.moduel('service', ['service.part1','service.part2']);
EDIT (plunker):
http://plnkr.co/edit/i75A5CQeSptQjaxvR8qi?p=preview

Categories