@ngdoc overview @name Interpolation @sortOrder 275 @description # Interpolation and data-binding Interpolation markup with embedded {@link guide/expression expressions} is used by AngularJS to provide data-binding to text nodes and attribute values. An example of interpolation is shown below: ```html Hello {{username}}! ``` ### How text and attribute bindings work During the compilation process the {@link ng.$compile compiler} uses the {@link ng.$interpolate $interpolate} service to see if text nodes and element attributes contain interpolation markup with embedded expressions. If that is the case, the compiler adds an interpolateDirective to the node and registers {@link ng.$rootScope.Scope#$watch watches} on the computed interpolation function, which will update the corresponding text nodes or attribute values as part of the normal {@link ng.$rootScope.Scope#$digest digest} cycle. Note that the interpolateDirective has a priority of 100 and sets up the watch in the preLink function. ### How the string representation is computed If the interpolated value is not a `String`, it is computed as follows: - `undefined` and `null` are converted to `''` - if the value is an object that is not a `Number`, `Date` or `Array`, $interpolate looks for a custom `toString()` function on the object, and uses that. Custom means that `myObject.toString !== Object.prototype.toString`. - if the above doesn't apply, `JSON.stringify` is used. ### Binding to boolean attributes Attributes such as `disabled` are called `boolean` attributes, because their presence means `true` and their absence means `false`. We cannot use normal attribute bindings with them, because the HTML specification does not require browsers to preserve the values of boolean attributes. This means that if we put an AngularJS interpolation expression into such an attribute then the binding information would be lost, because the browser ignores the attribute value. In the following example, the interpolation information would be ignored and the browser would simply interpret the attribute as present, meaning that the button would always be disabled. ```html Disabled: ``` For this reason, AngularJS provides special `ng`-prefixed directives for the following boolean attributes: {@link ngDisabled `disabled`}, {@link ngRequired `required`}, {@link ngSelected `selected`}, {@link ngChecked `checked`}, {@link ngReadonly `readOnly`} , and {@link ngOpen `open`}. These directives take an expression inside the attribute, and set the corresponding boolean attribute to true when the expression evaluates to truthy. ```html Disabled: ``` ### `ngAttr` for binding to arbitrary attributes Web browsers are sometimes picky about what values they consider valid for attributes. For example, considering this template: ```html ``` We would expect AngularJS to be able to bind to this, but when we check the console we see something like `Error: Invalid value for attribute cx="{{cx}}"`. Because of the SVG DOM API's restrictions, you cannot simply write `cx="{{cx}}"`. With `ng-attr-cx` you can work around this problem. If an attribute with a binding is prefixed with the `ngAttr` prefix (denormalized as `ng-attr-`) then during the binding it will be applied to the corresponding unprefixed attribute. This allows you to bind to attributes that would otherwise be eagerly processed by browsers (e.g. an SVG element's `circle[cx]` attributes). When using `ngAttr`, the `allOrNothing` flag of {@link ng.$interpolate $interpolate} is used, so if any expression in the interpolated string results in `undefined`, the attribute is removed and not added to the element. For example, we could fix the example above by instead writing: ```html ``` If one wants to modify a camelcased attribute (SVG elements have valid camelcased attributes), such as `viewBox` on the `svg` element, one can use underscores to denote that the attribute to bind to is naturally camelcased. For example, to bind to `viewBox`, we can write: ```html ``` Other attributes may also not work as expected when they contain interpolation markup, and can be used with `ngAttr` instead. The following is a list of known problematic attributes: - **size** in `