Search code examples
angularangular2-templatestring-interpolationtemplate-literalsproperty-binding

camelCase to lowercase html attribute conversion in Angular innerHtml binding


In my component I have a template literal string containing an HTML tag with an camelCase attribute in it:

htmlString = `<mat-icon svgIcon="edit" ...></mat-icon>`;

This string gets assembled as a property of an object in an array forEach loop.

For several reasons in the template I need to output this in an innerHtml attribute within a *ngFor loop:

<li *ngFor="let foo of foos" [innerHTML]="foo.htmlString"></li>

(This is a simplified code example of my implementation.)

I found out that in the output the svgIcon attribute is rendered in lowercase svgicon, see DOM inspector output:

<li _ngcontent-qui-c96="">
  <mat-icon svgicon="edit"></mat-icon>
</li>

Bug or feature? Couldn't find any info on this behaviour. Thanks for any hint!


Solution

  • Attributes are indeed all converted to lowercase by Angular, don't worry about that.

    Also, the point you are raising as a side-effect is interesting and might need some explanation: you use innerHtml with an Angular component (mat-icon, it is not a standard HTML tag).

    So, anyway, it will fail: a web browser does not know how to render a mat-icon.

    For a mat-icon to be rendered, it must go through the Angular template engine: Angular will see mat-icon, and will pull the component definition/template, and render it in HTML terms (DOM), that a browser can understand.

    Typically in your case, you should use:

    <li *ngFor="let foo of foos">
      <mat-icon [svgIcon]="foo.icon" ...></mat-icon>
    </li>
    

    And if your components are more complicated, you can explore using content projection with ng-content.