0

I have an odd issue with Angular 2 - possibly a bug? - where I cannot print the same variable in a template twice within the same HTML tag.

The below code gives undecipherable errors.

  <div class="panel panel-default" *ngFor="let trust of trusts">
      <div class="panel-heading" role="tab" id="name{{trust.id}}">
          <h4 class="panel-title">
              <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse{{trust.id}}" aria-expanded="true" aria-controls="collapse{{trust.id}}">
                  {{trust.name}}
              </a>
          </h4>
      </div>
      <div id="collapse{{trust.id}}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="name{{trust.id}}">
          <div class="panel-body">
              TBC
          </div>
      </div>
  </div>

Whereas this code works fine.

  <div class="panel panel-default" *ngFor="let trust of trusts">
      <div class="panel-heading" role="tab" id="name{{trust.id}}">
          <h4 class="panel-title">
              <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse{{trust.id}}" aria-expanded="true" aria-controls="collapse1">
                  {{trust.name}}
              </a>
          </h4>
      </div>
      <div id="collapse{{trust.id}}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="name1">
          <div class="panel-body">
              TBC
          </div>
      </div>
  </div>

As you can clearly see, the only difference between the first and second block of code is that in the second, working block, I have removed the second reference to {{trust.id}} in two HTML tags.

Below are the errors...

consoleError — zone.js:420Unhandled Promise rejection: (8)
"Template parse errors:
Can't bind to 'aria-controls' since it isn't a known property of 'a'. (\"\" data-toggle=\"collapse\" data-parent=\"#accordion\" href=\"#collapse{{trust.id}}\" aria-expanded=\"true\" [ERROR ->]aria-controls=\"collapse{{trust.id}}\">
                      {{trust.name}}
                  </a>
\"): AppComponent@90:139
Can't bind to 'aria-labelledby' since it isn't a known property of 'div'. (\"</h4>
          </div>
          <div id=\"collapse{{trust.id}}\" class=\"panel-collapse collapse\" role=\"tabpanel\" [ERROR ->]aria-labelledby=\"name{{trust.id}}\">
              <div class=\"panel-body\">
                  TBC
\"): AppComponent@95:83"
"; Zone:"
"<root>"
"; Task:"
"Promise.then"
"; Value:"
SyntaxError
"BaseError@http://localhost:4200/vendor.bundle.js:64381:20 [<root>]
SyntaxError@http://localhost:4200/vendor.bundle.js:5720:21 [<root>]
parse@http://localhost:4200/vendor.bundle.js:17586:82 [<root>]
_compileTemplate@http://localhost:4200/vendor.bundle.js:47577:73 [<root>]
forEach@[native code] [<root>]
_compileComponents@http://localhost:4200/vendor.bundle.js:47460:26 [<root>]
createResult@http://localhost:4200/vendor.bundle.js:47342:37 [<root>]
run@http://localhost:4200/polyfills.bundle.js:5990:49 [<root> => <root>]
http://localhost:4200/polyfills.bundle.js:6412:60 [<root>]
runTask@http://localhost:4200/polyfills.bundle.js:6028:57 [<root> => <root>]
drainMicroTaskQueue@http://localhost:4200/polyfills.bundle.js:6310:42 [<root>]
promiseReactionJob@[native code] [<root>]"
consoleError — zone.js:420
_loop_1 — zone.js:449
drainMicroTaskQueue — zone.js:453
promiseReactionJob
consoleError — zone.js:422
Error

Any suggestions?

Max Griffin
  • 439
  • 2
  • 5
  • 11

1 Answers1

2

I think it should be

attr.aria-labelledby="name{{trust.id}}"

or

[attr.aria-labelledby]="'name' + trust.id"

to make it an attribute binding, instead of a property binding.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • That worked, thank you. Can you explain why that is needed for some attributes and not others? I don't use it for id="name{{trust.id}}" and others. Is it just that Angular recognises some attributes automatically and not others? Should I really be using attr.id="name{{trust.id}}"? – Max Griffin Feb 13 '17 at 14:32
  • Properties are predefined, attributes are arbitrary. Some attributes and properties are connected and reflect the value to each other (actually many or even most properties have matching attributes). There are some exceptions like `` where the attribute name `for` is reflected to the property `htmlFor` - probably because `for` is a JS keyword) Some more explanation http://stackoverflow.com/questions/6003819/properties-and-attributes-in-html (there might be better ones) – Günter Zöchbauer Feb 13 '17 at 14:38