16

Any idea how to access attributes values from inside the directive?

    angular.module('portal.directives', [])
        .directive('languageFlag', ['$routeParams', function(params) {
            return function(scope, element, attrs) {
                console.log(attrs["data-key"]); // returns undefined
                console.log(element.attr('data-key')); // returns {{data-key}}
                angular.element(element).css('border', '1px solid red');
            };
        }]);

Html code is:

<ul>
    <li ng-repeat="lng in flags">
        <a class="lngFlag {{flag.Key}}" data-key="{{flag.Key}}" data-id="{{lng.Id}}" ng-click="changeLangHash({'lng':lng.Id })" language-flag></a>
    </li>
</ul>

Thanks

1
  • just follow camel case in case of dash - Commented Apr 30, 2013 at 12:59

5 Answers 5

23

Use $observe:

Observing interpolated attributes: Use $observe to observe the value changes of attributes that contain interpolation (e.g. src="{{bar}}"). Not only is this very efficient but it's also the only way to easily get the actual value because during the linking phase the interpolation hasn't been evaluated yet and so the value is at this time set to undefined. -- directives doc

return function(scope, element, attrs) {
    attrs.$observe('key', function(value) {
        console.log('key=', value);
    });
}

As @FMM mentioned in a comment, data is stripped by Angular when it normalizes the attribute name, hence the use of key above, rather than dataKey.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. It works on all attributes except for the ones with snake notations. Such as data-something. But I accept your answer because it actually works with other attributes. I appreciate your effort and time.
It's likely that angular is trimming the data prefix (docs.angularjs.org/guide/directive): "Optionally the directive can be prefixed with x-, or data- to make it HTML validator compliant." It's probably a bad idea to start your (logical) attribute names with "data".
10

try attrs["dataKey"] - this is the way that html parses attributes with dash (-). if you want the value from the scope instead of {{something}}, you can do two things:

scope[attrs['dataKey']] - will work but shouldn't do this

or use $parse but then don't use ``{{}}`

app.directive('languageFlag', ['$routeParams','$parse', function(params,$parse) {
  return function(scope, element, attrs) {
    var value =  $parse(attrs.dataKey)(scope);
    console.log(value);
    angular.element(element).css('border', '1px solid red');
  };
}]);

or you can use $interpolate the same way like $parse but with {{}}

3 Comments

Thanks for answering. console.log(attrs["dataKey"]); // = undefined console.log(scope[attrs['dataKey']]); // = undefined I even removed all the {{}} and tried .$parse but still 'undefined'. Isn't there a way to simply access the underlying model at bind time?
Passing parent scope to the $parse (ex: $parse(attrs.uid)($scope.$parent) ) solved my issue
@g00fy But what if the attribute is a two way binded value? My code will only parse it on directive load, but never notice the changes made to the variable (from the parent scope).
4

angular strips 'data-' off any attributes, so if your attribute is 'data-key', just use 'key', not 'dataKey'

4 Comments

I have a attribute with name "data-actiontype" with just actiontype I am not getting the data from that attribute. Is that name is predefined ?
@Kathir Hard to say without seeing your code. Hopefully you've figured it out since you asked 14 hours ago. If not, you should be able to look at the answers on this page and try a couple different things, figure it out.
Thanks for your reply. Please see my tag below <input type="button" value="Ok" id="" ng-click="getAttributejs($event)" class="" data-actiontype="kathir" /> Currently I am removing data- from tag. I am not figured out still.
@Kathir you might want to post a new question, i and everyone else really need to see your angular directive code. It'll likely get answered pretty quick. Or put together a codepen/JSfiddler and provide that link
1

I would suggest using object notation if you are inside the link function of the directive, which gets the attrs parameter:

attrs.yourAttributeName

Comments

0

Another issue I discovered is that $attr will convert attribute names to lower-casing.

<input myTest="test" />

Value can be obtained with this... attr["mytest"]

i.e.

...link: function (scope, element, attr) { console.log(attr["mytest"]); ...}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.