π§Ύ AngularJS Decorators & Metadata β Extend Behavior of Services, Directives, and Components (2025 Guide)
π§² Introduction β What Are Decorators in AngularJS?
While modern Angular (2+) uses TypeScript-based decorators like @Component() or @Injectable(), AngularJS (1.x) supports a different kind of decorator patternβone that allows you to modify or enhance services and directives at runtime.
In AngularJS, decorators are used with the $provide.decorator() method and serve as a powerful way to:
- Wrap existing services
- Add logging, caching, or metrics
- Override or extend directive behaviors
- Implement cross-cutting concerns like error handling or authentication
π― In this guide, youβll learn:
- What
$provide.decoratoris and how it works - How to decorate services and directives in AngularJS
- Use cases for AngularJS decorators
- Differences between AngularJS decorators and Angular 2+ decorators
π§© Understanding $provide.decorator in AngularJS
The $provide.decorator() method lets you intercept and modify services before they are injected into any component or controller.
π§ Syntax:
app.config(function($provide) {
$provide.decorator('serviceName', function($delegate) {
// Modify $delegate (original service)
return $delegate;
});
});
β
$delegate is the original instance of the service being decorated.
π§ͺ Decorate a Service Example
β Original Service
app.service('MathService', function() {
this.add = function(a, b) {
return a + b;
};
});
β Add Logging with Decorator
app.config(function($provide) {
$provide.decorator('MathService', function($delegate) {
const originalAdd = $delegate.add;
$delegate.add = function(a, b) {
console.log('Adding:', a, '+', b);
return originalAdd(a, b);
};
return $delegate;
});
});
β
Now, every call to MathService.add() will log its arguments before executing.
π Decorating Directives (Advanced Use)
β Extend an Existing Directive
Letβs say you want to modify the behavior of ngClick.
app.config(function($provide) {
$provide.decorator('ngClickDirective', function($delegate) {
const original = $delegate[0];
const newCompile = function() {
const link = original.link;
original.link = function(scope, element, attrs) {
console.log('ngClick triggered:', attrs.ngClick);
link.apply(this, arguments);
};
return original;
};
$delegate[0].compile = newCompile;
return $delegate;
});
});
β
Logs every ngClick usageβperfect for debugging, analytics, or tracking.
π Metadata in AngularJS
AngularJS doesnβt use decorator metadata like Angular 2+’s @Component, @Injectable, or reflection-based @Inject(). Instead, metadata is defined via:
- Module definitions
- Dependency injection annotations
- Directive configuration objects
β Example Directive Metadata
app.directive('helloWorld', function() {
return {
restrict: 'E',
template: '<h1>Hello, {{name}}</h1>',
scope: {
name: '='
}
};
});
β
The metadata here includes restrict, template, and scope.
π§ Real-World Use Cases for AngularJS Decorators
| Use Case | What You Decorate | Why |
|---|---|---|
| Add logging to services | $http, custom services | Debug API calls |
| Modify directive behavior | ngClick, ngModel | Add validation, logging, tracking |
| Inject global error handling | $exceptionHandler | Catch and report client-side errors |
| Add caching | API services | Reduce server requests, speed up UX |
| Analytics | Button/directive usage | Track user behavior |
π οΈ Best Practices
βοΈ Always return $delegate after modification
βοΈ Keep decorator logic minimal and modular
βοΈ Decorate services before application bootstraps
βοΈ Use decorators for cross-cutting concerns (e.g., logging, auth)
βοΈ Avoid mutating too many core directivesβmay cause instability
βοΈ AngularJS vs Angular (2+) Decorators
| Feature | AngularJS (1.x) | Angular (2+) |
|---|---|---|
| Decorator Syntax | $provide.decorator() | @Component(), @Injectable() |
| Applied To | Services, directives | Classes, properties |
| Metadata Usage | Config object | TypeScript decorators + metadata |
| Use Case | Runtime service patching | Compile-time annotations |
| Dependency Injection | Function parameter strings | TypeScript reflection & metadata |
π Summary β Recap & Next Steps
AngularJS decorators provide a flexible and powerful way to enhance services and directives at runtime. While they differ from TypeScript-style decorators in modern Angular, they still allow developers to inject logic like logging, caching, and tracking across an application.
π Key Takeaways:
- Use
$provide.decoratorto wrap services and directives - Decorators help implement cross-cutting concerns
- Metadata in AngularJS is defined through config objects, not annotations
- Avoid overuse of decorators on core directives unless needed
βοΈ Real-world Relevance:
Useful in legacy AngularJS projects for analytics, debugging, performance optimization, and structured enhancement without rewriting the app.
β FAQ β AngularJS Decorators & Metadata
β What is $provide.decorator used for in AngularJS?
β
It allows you to modify or wrap existing services or directives at runtime before they’re injected.
β Can I decorate AngularJS directives?
β
Yes. You can override or extend directive compile/link functions using $provide.decorator.
β Does AngularJS support TypeScript-style decorators?
β No. Those are exclusive to Angular 2+ and use TypeScript metadata reflection.
β Where is metadata defined in AngularJS?
β
Itβs defined in module definitions, directive config objects, and dependency injection annotations.
Share Now :
