292

Provided an HTML element of type div, how to set the value of its id attribute, which is the concatenation of a scope variable and a string ?

Th. Ma.
  • 9,432
  • 5
  • 31
  • 46

7 Answers7

422

ngAttr directive can totally be of help here, as introduced in the official documentation

https://docs.angularjs.org/guide/interpolation#-ngattr-for-binding-to-arbitrary-attributes

For instance, to set the id attribute value of a div element, so that it contains an index, a view fragment might contain

<div ng-attr-id="{{ 'object-' + myScopeObject.index }}"></div>

which would get interpolated to

<div id="object-1"></div>
Th. Ma.
  • 9,432
  • 5
  • 31
  • 46
  • 2
    Where does `myScopeObject` come from? Where would I define it? – Jan Aagaard Oct 06 '14 at 08:26
  • 1
    @JanAagaard Let us assume `myScopeObject` is a property of a `scope` object exposed using a controller. Please see also https://docs.angularjs.org/guide/controller. Is that clear enough for you or shall I elaborate further? – Th. Ma. Oct 06 '14 at 13:03
  • i did ng-attr-id="{{ 'Panel' + file.Id }}" but it does not generate id="Panel12312" for me :( – Manuel Maestrini May 23 '15 at 05:47
  • 17
    Aren't the following two identical in behavior: `
    ` and `
    ` ? The docs seem to say prepending `ng-attr-` is to help out for cases where the element is something non-standard, like not a `
    `. Am I reading the docs right?
    – broc.seib Jul 09 '15 at 01:41
  • Hi please check this is not working for me ng-attr-id="{{'note_'+Note.NoteId}}" – Ankit Apr 25 '17 at 12:56
  • 4
    @broc.seib using nd-attr is not only about standard. This is good practice because HTML interpreter can assign id to the element before angular gets loaded. And ng-attr ensures to assign id to the element only when angular gets loaded. same is the case for ng-src in tag. – Ankit Apr 25 '17 at 13:00
  • This answer is wrong. @broc.seib is right, according to the article linked to in this answer there are few situations where `ng-attr-` is necessary; `id` is not one of them. – omikes Dec 28 '17 at 19:42
80

This thing worked for me pretty well:

<div id="{{ 'object-' + $index }}"></div>

Tanveer Shaikh
  • 1,678
  • 14
  • 27
  • Time flies and perhaps, the most intuitive syntax now just works as expected. I remember having some issues while iterating over a list. – Th. Ma. Jan 13 '15 at 11:24
  • 2
    This will work correct in 90% of cases but you may sometimes get errors which are hard to debug. You should use ng-attr-id instead. – Baki Jun 03 '16 at 13:32
  • `ng-attr-id` is advantageous in 0% of situations. No examples can be provided, because there are none. – omikes Dec 28 '17 at 19:48
  • 8
    The `ng-attr-id` method is to ensure that the raw ng expression is never rendered in a valid HTML attribute (e.g. `id`, `label`, etc). This is to stop any downstream usage reading ng 'junk' (e.g. before render is complete, or after a js crash) – Overflew Jan 10 '18 at 00:38
60

In case you came to this question but related to newer Angular version >= 2.0.

<div [id]="element.id"></div>
Romil Patel
  • 12,879
  • 7
  • 47
  • 76
SoEzPz
  • 14,958
  • 8
  • 61
  • 64
  • 3
    That is not useful, the question is in context of AngularJS – btk Jan 30 '18 at 16:27
  • 20
    I agree; it’s only going to be useful to those members that find it useful. – SoEzPz Jan 30 '18 at 17:27
  • 29
    Some members still click on Angularjs links even though they are searching for Angular links. It's a bit confusing and errors will continue to happen. – SoEzPz Jan 30 '18 at 17:46
  • Be careful this is for Angular versions 2 or greater, Agree on this is out of context regarding the question, but the comment is very clear when saying which version of angular is applicable this approach – Luis Raúl Espinoza Barboza Jan 28 '22 at 15:22
  • 3
    Google doesn't seem to care much about the difference between AngularJS and Angular 2. This is helpful, thanks. – WesFanMan Oct 24 '22 at 14:35
27

A more elegant way I found to achieve this behaviour is simply:

<div id="{{ 'object-' + myScopeObject.index }}"></div>

For my implementation I wanted each input element in a ng-repeat to each have a unique id to associate the label with. So for an array of objects contained inside myScopeObjects one could do this:

<div ng-repeat="object in myScopeObject">
    <input id="{{object.name + 'Checkbox'}}" type="checkbox">
    <label for="{{object.name + 'Checkbox'}}">{{object.name}}</label>
</div>

Being able to generate unique ids on the fly can be pretty useful when dynamically adding content like this.

Cumulo Nimbus
  • 8,785
  • 9
  • 47
  • 68
  • I think this approach has issues. I am initializing the angular binding after the page is loaded. Now at times the div fails to load properly which I guess is because of clash of id of different div. – sumeet Jun 05 '15 at 09:01
  • Interesting. If you could reproduce your behavior in a plunker example I would be happy to check it out. Does using 'ng-attr-id=' work and just using 'id=' not? – Cumulo Nimbus Jun 07 '15 at 23:52
10

You could just simply do the following

In your js

$scope.id = 0;

In your template

<div id="number-{{$scope.id}}"></div>

which will render

<div id="number-0"></div>

It is not necessary to concatenate inside double curly brackets.

emil.c
  • 1,987
  • 2
  • 26
  • 46
6

Just <input id="field_name_{{$index}}" />

D. Mohamed
  • 75
  • 1
  • 4
-1

If you use this syntax:

<div ng-attr-id="{{ 'object-' + myScopeObject.index }}"></div>

Angular will render something like:

 <div ng-id="object-1"></div>

However this syntax:

<div id="{{ 'object-' + $index }}"></div>

will generate something like:

<div id="object-1"></div>
Chris Krycho
  • 3,125
  • 1
  • 23
  • 35
K Rajesh Kumar
  • 267
  • 3
  • 8