svg circle - Can't bind to cx since it isn't a known native property

20,500

Solution 1

In order to bind to SVG element attributes in Angular, you must prefix them with attr:

For your circle this will be:

<svg height="100" width="100">
      <circle fill="white"
          [attr.cx]="parsedSize/2"
          [attr.cy]="parsedSize/2"
          [attr.r]="radius"
          [attr.stroke]="stroke"
          [attr.stroke-width]="strokeWidthCapped"
          [attr.stroke-dasharray]="circumference"
          [attr.stroke-dashoffset]="(1 - parsedComplete) * circumference"/>
</svg>

I am not entirely sure if it should be [attr.stroke-width] or [attr.strokeWidth], but give it a shot.

You need to use the attr prefix when the attribute has no property associated

Solution 2

Just thought I'd chime in if anyone is still using AngularJS. Use the ng-attr- prefix for attributes to interpolate:

 <svg height="100" width="100">
  <circle fill="white"
      cx="{{parsedSize/2}}"
      cy="{{parsedSize/2}}"
      r="{{radius}}"
      stroke="{{stroke}}"
      stroke-width="{{strokeWidthCapped}}"
      stroke-dasharray="{{circumference}}"
      stroke-dashoffset="{{(1 - parsedComplete) * circumference}}"/>

Becomes:

 <svg height="100" width="100">
  <circle fill="white"
      ng-attr-cx="{{parsedSize/2}}"
      ng-attr-cy="{{parsedSize/2}}"
      ng-attr-r="{{radius}}"
      ng-attr-stroke="{{stroke}}"
      ng-attr-stroke-width="{{strokeWidthCapped}}"
      ng-attr-stroke-dasharray="{{circumference}}"
      ng-attr-stroke-dashoffset="{{(1 - parsedComplete) * circumference}}"/>

Note that you keep the curly braces in this case.

Share:
20,500
Sharmile Murugaraj
Author by

Sharmile Murugaraj

Updated on July 15, 2021

Comments

  • Sharmile Murugaraj
    Sharmile Murugaraj almost 3 years

    I need to do a progress arc based on the calculated percentage, I have created a custom directive to access the svg attributes from the user, while updating that in my template, I am getting the following error:

    Can't bind to 'cx' since it isn't a known native property
    Can't bind to 'cy' since it isn't a known native property

    etc..

    I am getting these sorts of errors for all the svg attributes.

    Below is my code in jade:

    progress-arc([size]="200", [strokeWidth]="20", [stroke]="red", [complete]="0.8")
    

    Below is my directive code:

    import {Component,Input,AfterViewInit} from '@angular/core';
    
    @Component({
      selector:'progress-arc',
      template:`
       <svg height="100" width="100">
          <circle fill="white"
              cx="{{parsedSize/2}}"
              cy="{{parsedSize/2}}"
              r="{{radius}}"
              stroke="{{stroke}}"
              stroke-width="{{strokeWidthCapped}}"
              stroke-dasharray="{{circumference}}"
              stroke-dashoffset="{{(1 - parsedComplete) * circumference}}"/>
      </svg>`,
      providers: [],
      directives: []
    })
    export class ProgressArc implements AfterViewInit {
     @Input('size') size:string;
     @Input('strokeWidth') strokeWidth:string;
     @Input('stroke') stroke:string;
      @Input('complete') complete:string;
      parsedStrokeWidth:number;
      parsedSize:number;
      parsedComplete:number;
      strokeWidthCapped:number;
      radius:number;
      circumference:number;
    
      ngAfterViewInit() {
        this.parsedSize = parseFloat(this.size);
        this.parsedStrokeWidth = parseFloat(this.strokeWidth);
        this.parsedComplete = parseFloat(this.complete);
        this.strokeWidthCapped = Math.min(this.parsedStrokeWidth, this.parsedSize / 2 - 1);
        this.radius = Math.max((this.parsedSize - this.strokeWidthCapped) / 2 - 1, 0);
        this.circumference = 2 * Math.PI * this.radius;
      }
    }
    

    Can someone tell me where I am going wrong?

  • David Faure
    David Faure over 6 years
    it is working but WHY sometimes we need attr. and somestines no, that is non sense (edit: I'm posting a question right now)
  • Poul Kruijt
    Poul Kruijt over 6 years
    Search for the difference between html properties and attributes. If you are binding to attributes you need the prefix
  • GreenEyedAndy
    GreenEyedAndy almost 6 years
    @PierreDuc can you tell me how the binding looks like if I want to bind two values for stroke-dasharray. something like: [attr.stroke-dasharray]="circumference circumference"
  • Poul Kruijt
    Poul Kruijt almost 6 years
    @GreenEyedAndy sure, you can do it like this: [attr.stroke-dasharray]="circum1 + ', ' + circum2". Or you can do it like this. [attr.stroke-dasharray]="{{circum1}}, {{circum2}}". Whatever you think is more legible.
  • WebWanderer
    WebWanderer over 4 years
    This is still valid as of Angular 8.x
  • Najam Us Saqib
    Najam Us Saqib over 3 years
    [fill]="myColorVariable" its not working. i want to show fill color for selected line.
  • Poul Kruijt
    Poul Kruijt over 3 years
    @NajamUsSaqib as the answer said: [attr.fill]="myColorVariable"
  • Najam Us Saqib
    Najam Us Saqib over 3 years
    somehow i managed it to work with css. [ngStyle]="{fill: myColorvariable}"
  • Poul Kruijt
    Poul Kruijt over 3 years
    @NajamUsSaqib sure that works too. Or [style.fill]="myColorVariable". Did you try the [attr.fill] though?
  • Najam Us Saqib
    Najam Us Saqib over 3 years
    @PoulKruijt Take a Look at this. stackoverflow.com/questions/64657678/…