Rules that establish consistent code organization, dependency injection patterns, and development practices for maintainable AngularJS applications.
Requires consistent dependency injection syntax across the application.
/**
* Require a consistent DI syntax
* Enforces one of several DI patterns for consistency
*/
const di = {
meta: {
docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/di.md" };
schema: [{
type: "string",
enum: ["function", "array", "$inject"]
}];
};
create: (context: ESLintContext) => ESLintVisitor;
};Usage Examples:
// Configuration: ["error", "array"]
// ✓ GOOD - Array notation
angular.module('myApp').controller('MyController', ['$scope', '$http', function($scope, $http) {
// controller logic
}]);
// Configuration: ["error", "$inject"]
// ✓ GOOD - $inject property
function MyController($scope, $http) {
// controller logic
}
MyController.$inject = ['$scope', '$http'];
angular.module('myApp').controller('MyController', MyController);
// Configuration: ["error", "function"]
// ✓ GOOD - Function parameter names (not minification-safe)
angular.module('myApp').controller('MyController', function($scope, $http) {
// controller logic
});Requires dependency injection parameters to be sorted alphabetically.
/**
* Require DI parameters to be sorted alphabetically
* Improves code readability and consistency
*/
const diOrder = {
meta: {
docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/di-order.md" };
schema: [];
};
create: (context: ESLintContext) => ESLintVisitor;
};Usage Example:
// ✗ BAD - Dependencies not in alphabetical order
angular.module('myApp').controller('MyController', ['$scope', '$http', '$location', function($scope, $http, $location) {}]);
// ✓ GOOD - Dependencies sorted alphabetically
angular.module('myApp').controller('MyController', ['$http', '$location', '$scope', function($http, $location, $scope) {}]);Requires unittest inject functions to only consist of assignments from injected values.
/**
* Unittest inject functions should only consist of assignments from injected values to describe block variables
* Keeps test setup clean and focused
*/
const dumbInject = {
meta: {
docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/dumb-inject.md" };
schema: [];
};
create: (context: ESLintContext) => ESLintVisitor;
};Usage Example:
// ✗ BAD - Complex logic in inject
describe('MyController', function() {
var $scope, $http;
beforeEach(inject(function(_$rootScope_, _$http_) {
$scope = _$rootScope_.$new();
$http = _$http_;
$scope.items = []; // Additional logic
$http.get('/api/data'); // Service calls
}));
});
// ✓ GOOD - Simple assignments only
describe('MyController', function() {
var $scope, $http;
beforeEach(inject(function(_$rootScope_, _$http_) {
$scope = _$rootScope_.$new();
$http = _$http_;
}));
});Requires and specifies a consistent function style for components.
/**
* Require and specify a consistent function style for components ('named' or 'anonymous')
* Enforces consistent function declaration patterns
* Linked to John Papa's Angular Style Guide y024
*/
const functionType = {
meta: {
docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/function-type.md" };
schema: [{
type: "string",
enum: ["named", "anonymous"]
}];
};
create: (context: ESLintContext) => ESLintVisitor;
};Usage Example:
// Configuration: ["error", "named"]
// ✓ GOOD - Named functions
function UserController($scope) {
// controller logic
}
angular.module('myApp').controller('UserController', UserController);
// Configuration: ["error", "anonymous"]
// ✓ GOOD - Anonymous functions
angular.module('myApp').controller('UserController', function($scope) {
// controller logic
});Requires a consistent order of module dependencies.
/**
* Require a consistent order of module dependencies
* Enforces alphabetical ordering of module dependencies
*/
const moduleDependencyOrder = {
meta: {
docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/module-dependency-order.md" };
schema: [{
type: "object",
properties: {
grouped: { type: "boolean" },
prefix: { type: "string" }
}
}];
};
create: (context: ESLintContext) => ESLintVisitor;
};Usage Example:
// ✗ BAD - Dependencies not ordered
angular.module('myApp', ['ui.router', 'ngAnimate', 'myApp.users', 'myApp.admin']);
// ✓ GOOD - Dependencies in alphabetical order
angular.module('myApp', ['myApp.admin', 'myApp.users', 'ngAnimate', 'ui.router']);
// With grouping configuration - project modules first, then third-party
angular.module('myApp', ['myApp.admin', 'myApp.users', 'ngAnimate', 'ui.router']);Enforces using factory() instead of service() for consistency.
/**
* Use factory() instead of service()
* Promotes consistent service creation pattern
* Linked to John Papa's Angular Style Guide y040
*/
const noServiceMethod = {
meta: {
docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/no-service-method.md" };
schema: [];
};
create: (context: ESLintContext) => ESLintVisitor;
};Usage Example:
// ✗ BAD - Using service() method
angular.module('myApp').service('UserService', function($http) {
this.getUsers = function() {
return $http.get('/api/users');
};
});
// ✓ GOOD - Using factory() method
angular.module('myApp').factory('UserService', function($http) {
return {
getUsers: function() {
return $http.get('/api/users');
}
};
});Requires all dependency injection parameters to be located on their own line.
/**
* Require all DI parameters to be located in their own line
* Improves readability when dealing with many dependencies
*/
const oneDependencyPerLine = {
meta: {
docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/one-dependency-per-line.md" };
schema: [{
type: "object",
properties: {
matchNames: { type: "boolean" }
}
}];
};
create: (context: ESLintContext) => ESLintVisitor;
};Usage Example:
// ✗ BAD - Multiple dependencies on same line
angular.module('myApp').controller('MyController', ['$scope', '$http', '$location', function($scope, $http, $location) {}]);
// ✓ GOOD - One dependency per line
angular.module('myApp').controller('MyController', [
'$scope',
'$http',
'$location',
function($scope, $http, $location) {
// controller logic
}
]);Disallows different REST service patterns and specifies one approach.
/**
* Disallow different rest service and specify one of '$http', '$resource', 'Restangular'
* Enforces consistent HTTP client usage across the application
*/
const restService = {
meta: {
docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/rest-service.md" };
schema: [{
type: "string",
enum: ["$http", "$resource", "Restangular"]
}];
};
create: (context: ESLintContext) => ESLintVisitor;
};Usage Example:
// Configuration: ["error", "$http"]
// ✗ BAD - Using $resource when $http is required
angular.module('myApp').factory('UserService', function($resource) {
return $resource('/api/users/:id');
});
// ✓ GOOD - Using specified $http service
angular.module('myApp').factory('UserService', function($http) {
return {
getUsers: function() {
return $http.get('/api/users');
}
};
});Requires and specifies consistent use of $scope.digest() or $scope.apply().
/**
* Require and specify consistent use $scope.digest() or $scope.apply()
* Enforces consistent digest cycle triggering patterns
*/
const watchersExecution = {
meta: {
docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/watchers-execution.md" };
schema: [{
type: "string",
enum: ["$digest", "$apply"]
}];
};
create: (context: ESLintContext) => ESLintVisitor;
};Usage Example:
// Configuration: ["error", "$apply"]
// ✗ BAD - Using $digest when $apply is required
$scope.$digest();
// ✓ GOOD - Using specified $apply method
$scope.$apply();
// Configuration: ["error", "$digest"]
// ✓ GOOD - Using $digest for performance-critical scenarios
$scope.$digest();Development convention rules often support flexible configuration to match team preferences:
interface ConventionRuleConfig {
/** Specific pattern to enforce */
pattern?: "array" | "function" | "$inject" | "named" | "anonymous";
/** Enable special handling modes */
grouped?: boolean;
matchNames?: boolean;
/** Specify service types */
serviceType?: "$http" | "$resource" | "Restangular";
/** Prefix patterns */
prefix?: string;
}Configuration Examples:
// DI syntax preference
"angular/di": ["error", "array"]
// Function style preference
"angular/function-type": ["error", "named"]
// REST service standardization
"angular/rest-service": ["error", "$http"]
// Enhanced dependency line formatting
"angular/one-dependency-per-line": ["error", { "matchNames": true }]These rules help establish consistent development patterns that make code more maintainable, readable, and easier for teams to collaborate on.