How to protect angularJS controller from minify - angularjs

So I know that I need to use [] to secure my code before minification. For example:
app.controller('mainController', ['$scope', function($scope) {
$scope.message = 'HOORAY!';
}]);
But how to do that when I am not using app as global variable, I've got
(function () {
'use strict';
angular
.module('app')
.controller('loginCtrl', Controller);
function Controller($scope, authService) {
var vm = $scope;
vm.login = function(login_field, password_field) {
var loginData = {
login: login_field,
password: password_field
};
authService.login(loginData);
};
}
})();
How to prevent it from problems during minification?

The same way:
.controller('loginCtrl', ['$scope', 'authService', Controller]);
I strongly advise you to use ng-annotate, which allows using the simple syntax, and transforms it into minifiable code for you. That will make your code simpler, easier to read, and avoid a whole lot of bugs.

When a controller or a service is a named function like in code above, it looks best when it's annotated with $inject (see John Papa style guide).
angular
.module('app')
.controller('loginCtrl', Controller);
Controller.$inject = ['$scope', 'authService'];
function Controller($scope, authService) {...}
Hoisting allows to place the annotation right above injectable function.

I believe it should be the same way:
(function () {
'use strict';
angular
.module('app')
.controller('loginCtrl', ['$scope', 'authService', function($scope, authService) {
$scope.login = function(login_field, password_field) {
var loginData = {
login: login_field,
password: password_field
};
authService.login(loginData);
};
}]);
})();

One way you may try grunt-ngmin before the minification that will searches and replace the minification with minify-friendly code. Go to this link you will see example https://github.com/btford/grunt-ngmin#example

Related

Which one is correct way for initializing module,controller in angularJS?

Which one is correct way for initializing module,controller in angularJS
var myapp=angular.module('myApp', []);
myapp.controller('Ctrl1', Ctrl1);
myapp.controller('Ctrl2', Ctrl2);
Ctrl1.$inject = ['$scope', '$http'];
Ctrl2.$inject = ['$scope', '$http'];
function Ctrl1($scope, $http) {
}
function Ctrl2($scope, $http) {
}
or this way
var myapp=angular.module('myApp', []);
myapp.controller('Ctrl1', Ctrl1);
Ctrl1.$inject = ['$scope', '$http'];
function Ctrl1($scope, $http) {
}
myapp.controller('Ctrl2', Ctrl2);
Ctrl2.$inject = ['$scope', '$http'];
function Ctrl2($scope, $http) {
}
or doing this way
var myapp=angular.module('myApp', []);
myapp.controller('Ctrl1', ['$scope', '$http', function ($scope, $http) {} ]);
myapp.controller('Ctrl2', ['$scope', '$http', function ($scope, $http) {} ]);
I am confusing which way is correct and can you give give me the cirrect project structure of AngularJS frmawork
Any sample project for that in github always welcome
Some peoples says John Papa style which one correct way i mean most efficient way
The simpliest way is to write:
myapp.controller('Ctrl1', function($scope, $http) {
});
And you should use ngmin to parse your code before minification. It will automatically wrap the controller callback in ['$scope', '$http', function($scope, $http) {}] to avoid minification problem.
If you use gulp, use gulp-ngmin.
The second way should be the ideal way as because
It is easy to read.
Easy to maintain
Protected from minification by the injector.
Anyways all of them are correct.
But second way should be the best.
Also make sure that you wrap the code in the way to protect from variable name clashes:
(function(){
'use strict'; //another best practice
//then your code
})()
Angular's $inject method, we can explicitly declare our dependencies. This one may give problem for every controller injection. Other than you can use.
https://docs.angularjs.org/api/auto/service/$injector

Ionic. How inject ionicPlatform into the service?

I'd like to inject $ionicPlatform abstraction into the service, but seemed I'm doing this wrong way. How should I use $ionicPlatform with service?
(function () {
"use strict";
angular.module('service', []).service('BBNService', ["$ionicPlatform", function ($http, $localStorage, $ionicPlatform) {
This code making $ionicPlatform undefined.
Inject ionic dependency & Remove $http if you not using it as follows,
angular.module('service', ['ionic'])
.service('BBNService', ["$localStorage", "$ionicPlatform",
function ($localStorage, $ionicPlatform) {
}]);
It's undefined because you wrong the order. (use ionic.Platform)
Replace with this:
angular.module('service', [])
.service('BBNService', ["$http", "$localStorage",
function ($http, $localStorage) {
//use this
var $ionicPlatform = ionic.Platform;
}]);

route provider how to pass a dependency into a controller

if I have the following angularjs code route provider how can I pass through a dependency into the blaCtrl controller please?
Many thanks,
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/bla', { templateUrl: 'bla.html', controller: 'blaCtrl' });
trying to get something like
'use strict';
app.controller('blaCtrl', function ($scope) {
$scope.mydata = ['111', '222', '333']; // how can I change this to be a method call to a dependency, i.e.
$scope.mydata = mydependency.getData(); // example what I need
});
update
My app file looks like this - I'm still not getting the data displayed?
'use strict';
var app = angular.module('myApp', ['ngRoute']);
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/application', { templateUrl: 'partials/application.html', controller: 'myCtrl' });
$routeProvider.otherwise({ redirectTo: '/application' });
}]);
controller
'use strict';
app.controller('myCtrl', 'myService', function ($scope, myService) {
debugger; // doesn't get hit?
$scope.stuff = myService.getStuff();
});
console error
- I get this error in the console Error: [ng:areq] http://errors.angularjs.org/1.4.5/ng/areq?p0=applicationCtrl&p1=not%20a%20function%2C%20got%20string
There are 3 ways of dependency annotation according to angular docs.
Inline Array Annotation
In this case your controller defenition should look like:
'use strict';
app.controller('blaCtrl', ['$scope', 'mydependency', function ($scope, mydependency) {
$scope.mydata = mydependency.getData();
}]);
$inject Property Annotation
'use strict';
var blaCtrl = function ($scope, mydependency) {
$scope.mydata = mydependency.getData();
};
blaCtrl.$inject = ['$scope', 'mydependency'];
app.controller('blaCtrl', blaCtrl);
Implicit Annotation
This one you used in your example code to inject $scope variable. Not recommended, minificattion will broke such code.
'use strict';
app.controller('blaCtrl', function ($scope, mydependency) {
$scope.mydata = mydependency.getData();
});
The fact that you reference your controller not in HTML but in routeProvider doesn't make any difference.
You can pass a dependency to the controller from within the controller. You're injecting the $scope dependency already, and you can inject others like $location and $rootScope if you'd like.

Advantage of using $injector vs explicit DI declaration AngularJS

Just wondering if there's difference between:
angular.module('app', [])
.controller('myctrl', ['$scope', 'customService',
function($scope, customService) {
// use customService
}
]);
and using $injector
angular.module('app', [])
.controller('myctrl', ['$scope', '$injector',
function($scope, $injector) {
// get customService via injector and use it
$injector.get('customService');
}
]);
Sometimes I need to inject quite a few dependencies and my parameter list ends up to be lengthy. That's why I'm thinking the latter approach may be better for my scenario.
Does the difference affect testing or minification or any other reason?
You are on the right track. Look at John Papa's Style Guide. You will do the injection before the controller function.
/* recommended */
angular
.module('app')
.controller('Dashboard', Dashboard);
Dashboard.$inject = ['$location', '$routeParams', 'common', 'dataservice'];
function Dashboard($location, $routeParams, common, dataservice) {
}
Basically there is not much different, until you first encounter your circular dependency error while loading your module.
Simple Fiddle that demonstrates circular dependency.
Code (from fiddle):
angular.module('app', [])
.service('serviceA', function (serviceB) {
return {};
})
.service('serviceB', function (serviceA) {
return {};
})
.controller('myCtrl', function (serviceA, serviceB) {
});
Using $injector helps prevent that scenario because when you use it inside the Controller/Factory/Service/etc instead of injecting the first way, you are delaying the dependency and therefore solving the problem.
And a simple Fiddle that demonstrates how that problem is solved.
Code (from fiddle):
angular.module('app', [])
.service('serviceA', function (serviceB) {
return {
test: "it works!"
};
})
.service('serviceB', function ($injector) {
return {
test: function() {
var serviceA = $injector.get("serviceA");
return serviceA.test;
}
};
})
.controller('myCtrl', function ($scope, serviceA, serviceB) {
$scope.test = serviceB.test();
});

how to write modular angular controllers

Please feel free to rephrase the title as necessary.
I do know how to write controllers the modular way.
var controllers = {};
controllers.ToDoController = function($scope){
//...
};
But you can do the same as follows:
var app = angular.module('myApp', []);
app.controller('ToDoController', '$scope', '$location', function($scope, $location){
//...
});
Above you are defining the arguments for the controller method. How do we do this in the first approach?
This is achieved using dependency injection:
var controllers = {};
controllers.ToDoController = function($scope, $location) {
//...
};
controllers.ToDoController.$inject = ['$scope', '$location'];
You can also check the official docs and examples here

Resources