Reader Stacks

The ng-init Directive: What Replaced It in Modern Angular

ng-init was an AngularJS (1.x) directive that never carried over to modern Angular — component lifecycle hooks are the direct, more structured replacement.

The ng-init Directive: What Replaced It in Modern Angular

ng-init was a directive from AngularJS (version 1.x, the original framework before the complete rewrite into modern Angular 2+) used for initializing a scope variable directly in a template — it has no direct equivalent in modern Angular, which handles initialization through component lifecycle hooks instead.

The old AngularJS pattern


{{ currentUser }} has {{ itemCount }} items

This ran inline in the template itself, directly setting scope variables as the element initialized — a pattern that modern Angular's component-based, TypeScript-first architecture doesn't support or need in the same way.

The modern Angular replacement: ngOnInit

@Component({
    selector: 'app-user-profile',
    template: `{{ currentUser }} has {{ itemCount }} items`
})
export class UserProfileComponent implements OnInit {
    currentUser: string = '';
    itemCount: number = 0;

    ngOnInit(): void {
        this.currentUser = 'Alex';
        this.itemCount = 0;
    }
}

ngOnInit() runs once, after Angular has initialized the component's inputs and bindings — the standard, structured place for initialization logic that ng-init handled inline in the older framework.

Initializing directly in property declarations, for simple static values

export class UserProfileComponent {
    currentUser: string = 'Alex';
    itemCount: number = 0;
}

For values that don't depend on any async data or injected service, initializing directly at property declaration is simpler than using ngOnInit() at all — reaching for the lifecycle hook specifically makes sense once initialization needs to happen after dependency injection or requires calling a service.

Initializing from an injected service

export class UserProfileComponent implements OnInit {
    currentUser: string = '';

    constructor(private userService: UserService) {}

    ngOnInit(): void {
        this.currentUser = this.userService.getCurrentUserName();
    }
}

This is exactly the kind of initialization ng-init couldn't have handled even in AngularJS — it required a genuinely simple, static value expressible directly in template syntax, whereas ngOnInit() can run arbitrary component logic, including calling injected services.

Why the shift away from template-based logic happened

AngularJS's template directives like ng-init mixed logic directly into HTML markup, which became difficult to test, trace, and maintain as applications grew — modern Angular's deliberate separation, keeping logic in TypeScript component classes and templates focused on presentation, was a core architectural decision in the framework's complete rewrite, not just a naming change.

If you encounter ng-init in an old codebase or tutorial

Seeing ng-init in any code sample is a reliable signal that the sample is written for AngularJS (1.x), not modern Angular (2 and later, including the current versions) — despite the similar name, these are genuinely different frameworks with incompatible syntax, and AngularJS-era tutorials generally shouldn't be followed directly for a modern Angular project.