Welcome to Knowledge Base!

KB at your finger tips

This is one stop global knowledge base where you can learn about all the products, solutions and support features.

Categories
All
Web-Angular
Angular - Introduction to services and dependency injection

Introduction to services and dependency injection link

Service is a broad category encompassing any value, function, or feature that an application needs. A service is typically a class with a narrow, well-defined purpose. It should do something specific and do it well.

Angular distinguishes components from services to increase modularity and reusability.

Ideally, a component's job is to enable only the user experience. A component should present properties and methods for data binding to mediate between the view and the application logic. The view is what the template renders and the application logic is what includes the notion of a model .

A component should use services for tasks that don't involve the view or application logic. Services are good for tasks such as fetching data from the server, validating user input, or logging directly to the console. By defining such processing tasks in an injectable service class , you make those tasks available to any component. You can also make your application more adaptable by injecting different providers of the same kind of service, as appropriate in different circumstances.

Angular doesn't enforce these principles. Instead, Angular helps you follow these principles by making it easy to factor your application logic into services. In Angular, dependency injection makes those services available to components.

Service examples link

Here's an example of a service class that logs to the browser console.

src/app/logger.service.ts (class)
      
      export class Logger {
  log(msg: any)   { console.log(msg); }
  error(msg: any) { console.error(msg); }
  warn(msg: any)  { console.warn(msg); }
}
    

Services can depend on other services. For example, here's a HeroService that depends on the Logger service, and also uses BackendService to get heroes. That service in turn might depend on the HttpClient service to fetch heroes asynchronously from a server.

src/app/hero.service.ts (class)
      
      export class HeroService {
  private heroes: Hero[] = [];

  constructor(
    private backend: BackendService,
    private logger: Logger) { }

  getHeroes() {
    this.backend.getAll(Hero).then( (heroes: Hero[]) => {
      this.logger.log(`Fetched ${heroes.length} heroes.`);
      this.heroes.push(...heroes); // fill cache
    });
    return this.heroes;
  }
}
    

Dependency injection (DI) link

Dependency injection (DI) is the part of the Angular framework that provides components with access to services and other resources. Angular provides the ability for you to inject a service into a component to give that component access to the service.

The @Injectable() decorator defines a class as a service in Angular and allows Angular to inject it into a component as a dependency . Likewise, the @Injectable() decorator indicates that a component, class, pipe, or NgModule has a dependency on a service.

  • The injector is the main mechanism. Angular creates an application-wide injector for you during the bootstrap process, and additional injectors as needed. You don't have to create injectors.

  • An injector creates dependencies and maintains a container of dependency instances that it reuses, if possible.

  • A provider is an object that tells an injector how to obtain or create a dependency

For any dependency that you need in your app, you must register a provider with the application's injector, so that the injector can use the provider to create new instances. For a service, the provider is typically the service class itself.

A dependency doesn't have to be a service —it could be a function, for example, or a value.

When Angular creates a new instance of a component class, it determines which services or other dependencies that component needs by looking at the constructor parameter types. For example, the constructor of HeroListComponent needs HeroService .

src/app/hero-list.component.ts (constructor)
      
      constructor(private service: HeroService) { }
    

When Angular discovers that a component depends on a service, it first checks if the injector has any existing instances of that service. If a requested service instance doesn't yet exist, the injector makes one using the registered provider and adds it to the injector before returning the service to Angular.

When all requested services have been resolved and returned, Angular can call the component's constructor with those services as arguments.

The process of HeroService injection looks something like this.

Providing services link

You must register at least one provider of any service you are going to use. The provider can be part of the service's own metadata, making that service available everywhere, or you can register providers with specific modules or components. You register providers in the metadata of the service (in the @Injectable() decorator), or in the @NgModule() or @Component() metadata

  • By default, the Angular CLI command ng generate service registers a provider with the root injector for your service by including provider metadata in the @Injectable() decorator. The tutorial uses this method to register the provider of HeroService class definition.

          
          @Injectable({
     providedIn: 'root',
    })
        

    When you provide the service at the root level, Angular creates a single, shared instance of HeroService and injects it into any class that asks for it. Registering the provider in the @Injectable() metadata also allows Angular to optimize an app by removing the service from the compiled application if it isn't used, a process known as tree-shaking .

  • When you register a provider with a specific NgModule, the same instance of a service is available to all components in that NgModule. To register at this level, use the providers property of the @NgModule() decorator.

          
          @NgModule({
      providers: [
      BackendService,
      Logger
     ],
     
    })
        
  • When you register a provider at the component level, you get a new instance of the service with each new instance of that component. At the component level, register a service provider in the providers property of the @Component() metadata.

    src/app/hero-list.component.ts (component providers)
          
          @Component({
      selector:    'app-hero-list',
      templateUrl: './hero-list.component.html',
      providers:  [ HeroService ]
    })
        

For more detailed information, see the Dependency Injection section.

Last reviewed on Mon Feb 28 2022
Angular - Introduction to Angular concepts

Introduction to Angular concepts link

Angular is a platform and framework for building single-page client applications using HTML and TypeScript. Angular is written in TypeScript. It implements core and optional functionality as a set of TypeScript libraries that you import into your applications.

The architecture of an Angular application relies on certain fundamental concepts. The basic building blocks of the Angular framework are Angular components that are organized into NgModules . NgModules collect related code into functional sets; an Angular application is defined by a set of NgModules. An application always has at least a root module that enables bootstrapping, and typically has many more feature modules .

  • Components define views , which are sets of screen elements that Angular can choose among and modify according to your program logic and data
  • Components use services , which provide specific functionality not directly related to views. Service providers can be injected into components as dependencies , making your code modular, reusable, and efficient.

Modules, components and services are classes that use decorators . These decorators mark their type and provide metadata that tells Angular how to use them.

  • The metadata for a component class associates it with a template that defines a view. A template combines ordinary HTML with Angular directives and binding markup that allow Angular to modify the HTML before rendering it for display.

  • The metadata for a service class provides the information Angular needs to make it available to components through dependency injection (DI)

An application's components typically define many views, arranged hierarchically. Angular provides the Router service to help you define navigation paths among views. The router provides sophisticated in-browser navigational capabilities.

See the Angular Glossary for basic definitions of important Angular terms and usage.

For the sample application that this page describes, see the live example / download example .

Modules link

Angular NgModules differ from and complement JavaScript (ES2015) modules. An NgModule declares a compilation context for a set of components that is dedicated to an application domain, a workflow, or a closely related set of capabilities. An NgModule can associate its components with related code, such as services, to form functional units.

Every Angular application has a root module , conventionally named AppModule , which provides the bootstrap mechanism that launches the application. An application typically contains many functional modules.

Like JavaScript modules, NgModules can import functionality from other NgModules, and allow their own functionality to be exported and used by other NgModules. For example, to use the router service in your app, you import the Router NgModule.

Organizing your code into distinct functional modules helps in managing development of complex applications, and in designing for reusability. In addition, this technique lets you take advantage of lazy-loading —that is, loading modules on demand— to minimize the amount of code that needs to be loaded at startup.

For a more detailed discussion, see Introduction to modules.

Components link

Every Angular application has at least one component, the root component that connects a component hierarchy with the page document object model (DOM). Each component defines a class that contains application data and logic, and is associated with an HTML template that defines a view to be displayed in a target environment.

The @Component() decorator identifies the class immediately below it as a component, and provides the template and related component-specific metadata.

Decorators are functions that modify JavaScript classes. Angular defines a number of decorators that attach specific kinds of metadata to classes, so that the system knows what those classes mean and how they should work.

Learn more about decorators on the web.

Templates, directives, and data binding link

A template combines HTML with Angular markup that can modify HTML elements before they are displayed. Template directives provide program logic, and binding markup connects your application data and the DOM. There are two types of data binding:

Data bindings Details
Event binding Lets your application respond to user input in the target environment by updating your application data.
Property binding Lets you interpolate values that are computed from your application data into the HTML.

Before a view is displayed, Angular evaluates the directives and resolves the binding syntax in the template to modify the HTML elements and the DOM, according to your program data and logic. Angular supports two-way data binding , meaning that changes in the DOM, such as user choices, are also reflected in your program data.

Your templates can use pipes to improve the user experience by transforming values for display. For example, use pipes to display dates and currency values that are appropriate for a user's locale. Angular provides predefined pipes for common transformations, and you can also define your own pipes.

For a more detailed discussion of these concepts, see Introduction to components.

Services and dependency injection link

For data or logic that isn't associated with a specific view, and that you want to share across components, you create a service class. A service class definition is immediately preceded by the @Injectable() decorator. The decorator provides the metadata that allows other providers to be injected as dependencies into your class.

Dependency injection (DI) lets you keep your component classes lean and efficient. They don't fetch data from the server, validate user input, or log directly to the console; they delegate such tasks to services.

For a more detailed discussion, see Introduction to services and DI.

Routing link

The Angular Router NgModule provides a service that lets you define a navigation path among the different application states and view hierarchies in your application. It is modeled on the familiar browser navigation conventions:

  • Enter a URL in the address bar and the browser navigates to a corresponding page
  • Click links on the page and the browser navigates to a new page
  • Click the browser's back and forward buttons and the browser navigates backward and forward through the history of pages you've seen

The router maps URL-like paths to views instead of pages. When a user performs an action, such as clicking a link, that would load a new page in the browser, the router intercepts the browser's behavior, and shows or hides view hierarchies.

If the router determines that the current application state requires particular functionality, and the module that defines it hasn't been loaded, the router can lazy-load the module on demand.

The router interprets a link URL according to your application's view navigation rules and data state. You can navigate to new views when the user clicks a button or selects from a drop box, or in response to some other stimulus from any source. The router logs activity in the browser's history, so the back and forward buttons work as well.

To define navigation rules, you associate navigation paths with your components. A path uses a URL-like syntax that integrates your program data, in much the same way that template syntax integrates your views with your program data. You can then apply program logic to choose which views to show or to hide, in response to user input and your own access rules.

For a more detailed discussion, see Routing and navigation.

What's next link

You've learned the basics about the main building blocks of an Angular application. The following diagram shows how these basic pieces are related.

  • Together, a component and template define an Angular view
    • A decorator on a component class adds the metadata, including a pointer to the associated template
    • Directives and binding markup in a component's template modify views based on program data and logic
  • The dependency injector provides services to a component, such as the router service that lets you define navigation among views

Each of these subjects is introduced in more detail in the following pages.

  • Introduction to Modules
  • Introduction to Components
    • Templates and views
    • Component metadata
    • Data binding
    • Directives
    • Pipes
  • Introduction to services and dependency injection

When you're familiar with these fundamental building blocks, you can explore them in more detail in the documentation. To learn about more tools and techniques that are available to help you build and deploy Angular applications, see Next steps: tools and techniques.

Read article
Angular - Attribute binding

Attribute binding link

Attribute binding in Angular helps you set values for attributes directly. With attribute binding, you can improve accessibility, style your application dynamically, and manage multiple CSS classes or styles simultaneously.

See the live example / download example for a working example containing the code snippets in this guide.

Prerequisites link

  • Property Binding

Syntax link

Attribute binding syntax resembles property binding, but instead of an element property between brackets, you precede the name of the attribute with the prefix attr , followed by a dot. Then, you set the attribute value with an expression that resolves to a string.

      
      <p [attr.attribute-you-are-targeting]="expression"></p>
    

When the expression resolves to null or undefined , Angular removes the attribute altogether.

Binding ARIA attributes link

One of the primary use cases for attribute binding is to set ARIA attributes.

To bind to an ARIA attribute, type the following:

src/app/app.component.html
      
      <!-- create and set an aria attribute for assistive technology -->
<button type="button" [attr.aria-label]="actionName">{{actionName}} with Aria</button>
    

Binding to colspan link

Another common use case for attribute binding is with the colspan attribute in tables. Binding to the colspan attribute helps you to keep your tables programmatically dynamic. Depending on the amount of data that your application populates a table with, the number of columns that a row spans could change.

To use attribute binding with the <td> attribute colspan

  1. Specify the colspan attribute by using the following syntax: [attr.colspan] .
  2. Set [attr.colspan] equal to an expression.

In the following example, you bind the colspan attribute to the expression 1 + 1 .

src/app/app.component.html
      
      <!--  expression calculates colspan=2 -->
<tr><td [attr.colspan]="1 + 1">One-Two</td></tr>
    

This binding causes the <tr> to span two columns.

Sometimes there are differences between the name of property and an attribute.

colspan is an attribute of <td> , while colSpan with a capital "S" is a property. When using attribute binding, use colspan with a lowercase "s".

For more information on how to bind to the colSpan property, see the colspan and colSpan section of Property Binding.

What’s next link

  • Class & Style Binding
Last reviewed on Mon May 02 2022
Read article
Angular - Attribute directives

Attribute directives link

Change the appearance or behavior of DOM elements and Angular components with attribute directives.

See the live example / download example for a working example containing the code snippets in this guide.

Building an attribute directive link

This section walks you through creating a highlight directive that sets the background color of the host element to yellow.

  1. To create a directive, use the CLI command ng generate directive .

          
          ng generate directive highlight
        

    The CLI creates src/app/highlight.directive.ts , a corresponding test file src/app/highlight.directive.spec.ts , and declares the directive class in the AppModule .

    The CLI generates the default src/app/highlight.directive.ts as follows:

    src/app/highlight.directive.ts
          
          import { Directive } from '@angular/core';
    
    @Directive({
      selector: '[appHighlight]'
    })
    export class HighlightDirective {
    
    }
        

    The @Directive() decorator's configuration property specifies the directive's CSS attribute selector, [appHighlight] .

  2. Import ElementRef from @angular/core . ElementRef grants direct access to the host DOM element through its nativeElement property.

  3. Add ElementRef in the directive's constructor() to inject a reference to the host DOM element, the element to which you apply appHighlight .

  4. Add logic to the HighlightDirective class that sets the background to yellow.

    src/app/highlight.directive.ts
          
          import { Directive, ElementRef } from '@angular/core';
    
    @Directive({
      selector: '[appHighlight]'
    })
    export class HighlightDirective {
        constructor(private el: ElementRef) {
           this.el.nativeElement.style.backgroundColor = 'yellow';
        }
    }
        

Directives do not support namespaces.

src/app/app.component.avoid.html (unsupported)
      
      <p app:Highlight>This is invalid</p>
    

Applying an attribute directive link

  1. To use the HighlightDirective , add a <p> element to the HTML template with the directive as an attribute.

    src/app/app.component.html
          
          <p appHighlight>Highlight me!</p>
        

Angular creates an instance of the HighlightDirective class and injects a reference to the <p> element into the directive's constructor, which sets the <p> element's background style to yellow.

Handling user events link

This section shows you how to detect when a user mouses into or out of the element and to respond by setting or clearing the highlight color.

  1. Import HostListener from '@angular/core'.

    src/app/highlight.directive.ts (imports)
          
          import { Directive, ElementRef, HostListener } from '@angular/core';
        
  2. Add two event handlers that respond when the mouse enters or leaves, each with the @HostListener() decorator.

    src/app/highlight.directive.ts (mouse-methods)
          
          @HostListener('mouseenter') onMouseEnter() {
      this.highlight('yellow');
    }
    
    @HostListener('mouseleave') onMouseLeave() {
      this.highlight('');
    }
    
    private highlight(color: string) {
      this.el.nativeElement.style.backgroundColor = color;
    }
        

Subscribe to events of the DOM element that hosts an attribute directive, the <p> in this case, with the @HostListener() decorator.

The handlers delegate to a helper method, highlight() , that sets the color on the host DOM element, el .

The complete directive is as follows:

src/app/highlight.directive.ts
      
      @Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {

  constructor(private el: ElementRef) { }

  @HostListener('mouseenter') onMouseEnter() {
    this.highlight('yellow');
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.highlight('');
  }

  private highlight(color: string) {
    this.el.nativeElement.style.backgroundColor = color;
  }

}
    

The background color appears when the pointer hovers over the paragraph element and disappears as the pointer moves out.

Passing values into an attribute directive link

This section walks you through setting the highlight color while applying the HighlightDirective .

  1. In highlight.directive.ts , import Input from @angular/core .

    src/app/highlight.directive.ts (imports)
          
          import { Directive, ElementRef, HostListener, Input } from '@angular/core';
        
  2. Add an appHighlight @Input() property.

    src/app/highlight.directive.ts
          
          @Input() appHighlight = '';
        

    The @Input() decorator adds metadata to the class that makes the directive's appHighlight property available for binding.

  3. In app.component.ts , add a color property to the AppComponent .

    src/app/app.component.ts (class)
          
          export class AppComponent {
      color = 'yellow';
    }
        
  4. To simultaneously apply the directive and the color, use property binding with the appHighlight directive selector, setting it equal to color .

    src/app/app.component.html (color)
          
          <p [appHighlight]="color">Highlight me!</p>
        

    The [appHighlight] attribute binding performs two tasks:

    • Applies the highlighting directive to the <p> element
    • Sets the directive's highlight color with a property binding

Setting the value with user input link

This section guides you through adding radio buttons to bind your color choice to the appHighlight directive.

  1. Add markup to app.component.html for choosing a color as follows:

    src/app/app.component.html (v2)
          
          <h1>My First Attribute Directive</h1>
    
    <h2>Pick a highlight color</h2>
    <div>
      <input type="radio" name="colors" (click)="color='lightgreen'">Green
      <input type="radio" name="colors" (click)="color='yellow'">Yellow
      <input type="radio" name="colors" (click)="color='cyan'">Cyan
    </div>
    <p [appHighlight]="color">Highlight me!</p>
        
  2. Revise the AppComponent.color so that it has no initial value.

    src/app/app.component.ts (class)
          
          export class AppComponent {
      color = '';
    }
        
  3. In highlight.directive.ts , revise onMouseEnter method so that it first tries to highlight with appHighlight and falls back to red if appHighlight is undefined .

    src/app/highlight.directive.ts (mouse-enter)
          
          @HostListener('mouseenter') onMouseEnter() {
      this.highlight(this.appHighlight || 'red');
    }
        
  4. Serve your application to verify that the user can choose the color with the radio buttons.

Binding to a second property link

This section guides you through configuring your application so the developer can set the default color.

  1. Add a second Input() property to HighlightDirective called defaultColor .

    src/app/highlight.directive.ts (defaultColor)
          
          @Input() defaultColor = '';
        
  2. Revise the directive's onMouseEnter so that it first tries to highlight with the appHighlight , then with the defaultColor , and falls back to red if both properties are undefined .

    src/app/highlight.directive.ts (mouse-enter)
          
          @HostListener('mouseenter') onMouseEnter() {
      this.highlight(this.appHighlight || this.defaultColor || 'red');
    }
        
  3. To bind to the AppComponent.color and fall back to "violet" as the default color, add the following HTML. In this case, the defaultColor binding doesn't use square brackets, [] , because it is static.

    src/app/app.component.html (defaultColor)
          
          <p [appHighlight]="color" defaultColor="violet">
      Highlight me too!
    </p>
        

    As with components, you can add multiple directive property bindings to a host element.

The default color is red if there is no default color binding. When the user chooses a color the selected color becomes the active highlight color.

Deactivating Angular processing with NgNonBindable link

To prevent expression evaluation in the browser, add ngNonBindable to the host element. ngNonBindable deactivates interpolation, directives, and binding in templates.

In the following example, the expression {{ 1 + 1 }} renders just as it does in your code editor, and does not display 2 .

src/app/app.component.html
      
      <p>Use ngNonBindable to stop evaluation.</p>
<p ngNonBindable>This should not evaluate: {{ 1 + 1 }}</p>
    

Applying ngNonBindable to an element stops binding for that element's child elements. However, ngNonBindable still lets directives work on the element where you apply ngNonBindable . In the following example, the appHighlight directive is still active but Angular does not evaluate the expression {{ 1 + 1 }} .

src/app/app.component.html
      
      <h3>ngNonBindable with a directive</h3>
<div ngNonBindable [appHighlight]="'yellow'">This should not evaluate: {{ 1 +1 }}, but will highlight yellow.
</div>
    

If you apply ngNonBindable to a parent element, Angular disables interpolation and binding of any sort, such as property binding or event binding, for the element's children.

Last reviewed on Mon Feb 28 2022
Read article
Angular - Understanding binding

Understanding binding link

In an Angular template, a binding creates a live connection between a part of the UI created from a template (a DOM element, directive, or component) and the model (the component instance to which the template belongs). This connection can be used to synchronize the view with the model, to notify the model when an event or user action takes place in the view, or both. Angular's Change Detection algorithm is responsible for keeping the view and the model in sync.

Examples of binding include:

  • text interpolations
  • property binding
  • event binding
  • two-way binding

Bindings always have two parts: a target which will receive the bound value, and a template expression which produces a value from the model.

Syntax link

Template expressions are similar to JavaScript expressions. Many JavaScript expressions are legal template expressions, with the following exceptions.

You can't use JavaScript expressions that have or promote side effects, including:

  • Assignments ( = , += , -= , ... )
  • Operators such as new , typeof , or instanceof
  • Chaining expressions with ; or ,
  • The increment and decrement operators ++ and --
  • Some of the ES2015+ operators

Other notable differences from JavaScript syntax include:

  • No support for the bitwise operators such as | and &
  • New template expression operators, such as |

Expression context link

Interpolated expressions have a context—a particular part of the application to which the expression belongs. Typically, this context is the component instance.

In the following snippet, the expression recommended and the expression itemImageUrl2 refer to properties of the AppComponent .

src/app/app.component.html
      
      <h4>{{recommended}}</h4>
<img alt="item 2" [src]="itemImageUrl2">
    

An expression can also refer to properties of the template's context such as a template input variable or a template reference variable.

The following example uses a template input variable of customer .

src/app/app.component.html (template input variable)
      
      <ul>
  <li *ngFor="let customer of customers">{{customer.name}}</li>
</ul>
    

This next example features a template reference variable, #customerInput .

src/app/app.component.html (template reference variable)
      
      <label>Type something:
  <input #customerInput>{{customerInput.value}}
</label>
    

Template expressions cannot refer to anything in the global namespace, except undefined . They can't refer to window or document . Additionally, they can't call console.log() or Math.max() and are restricted to referencing members of the expression context.

Preventing name collisions link

The context against which an expression evaluates is the union of the template variables, the directive's context object—if it has one—and the component's members. If you reference a name that belongs to more than one of these namespaces, Angular applies the following precedence logic to determine the context:

  1. The template variable name.
  2. A name in the directive's context.
  3. The component's member names.

To avoid variables shadowing variables in another context, keep variable names unique. In the following example, the AppComponent template greets the customer , Padma.

An ngFor then lists each customer in the customers array.

src/app/app.component.ts
      
      @Component({
  template: `
    <div>
      <!-- Hello, Padma -->
      <h1>Hello, {{customer}}</h1>
      <ul>
        <!-- Ebony and Chiho in a list-->
        <li *ngFor="let customer of customers">{{ customer.value }}</li>
      </ul>
    </div>
  `
})
class AppComponent {
  customers = [{value: 'Ebony'}, {value: 'Chiho'}];
  customer = 'Padma';
}
    

The customer within the ngFor is in the context of an <ng-template> and so refers to the customer in the customers array, in this case Ebony and Chiho. This list does not feature Padma because customer outside of the ngFor is in a different context. Conversely, customer in the <h1> doesn't include Ebony or Chiho because the context for this customer is the class and the class value for customer is Padma.

Expression best practices link

When using a template expression, follow these best practices:

  • Use short expressions

Use property names or method calls whenever possible. Keep application and business logic in the component, where it is accessible to develop and test.

  • Quick execution

Angular executes a template expression after every change detection cycle. Many asynchronous activities trigger change detection cycles, such as promise resolutions, HTTP results, timer events, key presses, and mouse moves.

An expression should finish quickly to keep the user experience as efficient as possible, especially on slower devices. Consider caching values when their computation requires greater resources.

No visible side effects link

According to Angular's unidirectional data flow model, a template expression should not change any application state other than the value of the target property. Reading a component value should not change some other displayed value. The view should be stable throughout a single rendering pass.

Idempotent expressions reduce side effects

An idempotent expression is free of side effects and improves Angular's change detection performance. In Angular terms, an idempotent expression always returns exactly the same thing until one of its dependent values changes.

Dependent values should not change during a single turn of the event loop. If an idempotent expression returns a string or a number, it returns the same string or number if you call it twice consecutively. If the expression returns an object, including an array , it returns the same object reference if you call it twice consecutively.

What's next link

  • Property binding
  • Event binding
Last reviewed on Thu May 12 2022
Read article
Angular - Binding syntax

Binding syntax link

Data binding automatically keeps your page up-to-date based on your application's state. You use data binding to specify things such as the source of an image, the state of a button, or data for a particular user.

See the live example / download example for a working example containing the code snippets in this guide.

Data binding and HTML link

Developers can customize HTML by specifying attributes with string values. In the following example, class , src , and disabled modify the <div> , <img> , and <button> elements respectively.

      
      <div class="special">Plain old HTML</div>
<img src="images/item.png">
<button disabled>Save</button>
    

Use data binding to control things like the state of a button:

src/app/app.component.html
      
      <!-- Bind button disabled state to `isUnchanged` property -->
<button type="button" [disabled]="isUnchanged">Save</button>
    

Notice that the binding is to the disabled property of the button's DOM element, not the attribute. Data binding works with properties of DOM elements, components, and directives, not HTML attributes.

HTML attributes and DOM properties link

Angular binding distinguishes between HTML attributes and DOM properties.

Attributes initialize DOM properties and you can configure them to modify an element's behavior. Properties are features of DOM nodes.

  • A few HTML attributes have 1:1 mapping to properties; for example,

          
          id
        
  • Some HTML attributes don't have corresponding properties; for example,

          
          aria-*
        
  • Some DOM properties don't have corresponding attributes; for example,

          
          textContent
        

Remember that HTML attributes and DOM properties are different things, even when they have the same name.

In Angular, the only role of HTML attributes is to initialize element and directive state.

When you write a data binding, you're dealing exclusively with the DOM properties and events of the target object.

Example 1: an <input> link

When the browser renders <input type="text" value="Sarah"> , it creates a corresponding DOM node with a value property and initializes that value to "Sarah".

      
      <input type="text" value="Sarah">
    

When the user enters Sally into the <input> , the DOM element value property becomes Sally . However, if you look at the HTML attribute value using input.getAttribute('value') , you can see that the attribute remains unchanged —it returns "Sarah".

The HTML attribute value specifies the initial value; the DOM value property is the current value.

To see attributes versus DOM properties in a functioning app, see the live example / download example especially for binding syntax.

Example 2: a disabled button link

A button's disabled property is false by default so the button is enabled.

When you add the disabled attribute, you are initializing the button's disabled property to true which disables the button.

      
      <button disabled>Test Button</button>
    

Adding and removing the disabled attribute disables and enables the button. However, the value of the attribute is irrelevant, which is why you cannot enable a button by writing <button disabled="false">Still Disabled</button> .

To control the state of the button, set the disabled property instead.

Property and attribute comparison link

Though you could technically set the [attr.disabled] attribute binding, the values are different in that the property binding must be a boolean value, while its corresponding attribute binding relies on whether the value is null or not. Consider the following:

      
      <input [disabled]="condition ? true : false">
<input [attr.disabled]="condition ? 'disabled' : null">
    

The first line, which uses the disabled property, uses a boolean value. The second line, which uses the disabled attribute checks for null .

Generally, use property binding over attribute binding as a boolean value is easy to read, the syntax is shorter, and a property is more performant.

To see the disabled button example in a functioning application, see the live example / download example . This example shows you how to toggle the disabled property from the component.

Types of data binding link

Angular provides three categories of data binding according to the direction of data flow:

  • From source to view
  • From view to source
  • In a two-way sequence of view to source to view
Type Syntax Category
Interpolation
Property
Attribute
Class
Style
      
      {{expression}} 
[target]="expression"
    
One-way from data source to view target
Event
      
      (target)="statement"
    
One-way from view target to data source
Two-way
      
      [(target)]="expression"
    
Two-way

Binding types other than interpolation have a target name to the left of the equal sign. The target of a binding is a property or event, which you surround with square bracket ( [ ] ) characters, parenthesis ( ( ) ) characters, or both ( [( )] ) characters.

The binding punctuation of [] , () , [()] , and the prefix specify the direction of data flow.

  • Use [] to bind from source to view
  • Use () to bind from view to source
  • Use [()] to bind in a two-way sequence of view to source to view

Place the expression or statement to the right of the equal sign within double quote ( "" ) characters. For more information see Interpolation and Template statements.

Binding types and targets link

The target of a data binding can be a property, an event, or an attribute name. Every public member of a source directive is automatically available for binding in a template expression or statement. The following table summarizes the targets for the different binding types.

Type Target Examples
Property Element property
Component property
Directive property
alt , src , hero , and ngClass in the following:
      
      <img [alt]="hero.name" [src]="heroImageUrl">
<app-hero-detail [hero]="currentHero"></app-hero-detail>
<div [ngClass]="{'special': isSpecial}"></div>
    
Event Elementevent
Component event
Directive event
click , deleteRequest , and myClick in the following:
      
      <button type="button" (click)="onSave()">Save</button>
<app-hero-detail (deleteRequest)="deleteHero()"></app-hero-detail>
<div (myClick)="clicked=$event" clickable>click me</div>
    
Two-way Event and property
      
      <input [(ngModel)]="name">
    
Attribute Attribute (the exception)
      
      <button type="button" [attr.aria-label]="help">help</button>
    
Class class property
      
      <div [class.special]="isSpecial">Special</div>
    
Style style property
      
      <button type="button" [style.color]="isSpecial ? 'red' : 'green'">
    
Last reviewed on Mon Feb 28 2022
Read article