39

Is is possible to check whether a given attribute is present in a directive, ideally using isolate scope or in a worst case scenario the attributes object.

With a directive that looked something like this <project status></project>, I want to conditionally render a status icon, but only if the status attribute is present.

return {
  restrict: 'AE',
  scope: {
    status: '@'
  },
  link: function(scope, element, attrs) {
    scope.status === 'undefined'
  }
}

Ideally, it would be bound straight to the scope, so that it could be used in the template. However, the bound variable's value is undefined. The same goes for & read-only and = two-way bindings.

I know that it's trivially solved by adding a <project status='true'></project>, but for directives that I will use frequently, I'd rather not have to. (XHTML validity, is not an issue).

5
  • I know you mentioned it, but just wondering - did you try something like "status" in attrs and see what that evaluation is? Commented Sep 12, 2014 at 15:31
  • isn't "@" a one way text binding passed to the directive? so scope.status should be the text reading 'true', so long as you pass a variable into the directive as <code><project status="{{myScopeVariable}}"></project></code> Commented Sep 12, 2014 at 15:39
  • When you specify scope as an object like above, the directive creates a new isolate Scope which doesn't inherit properties from parent scope. Instead use scope: true to create a new scope (with access to parent scope properties), or scope: false to have directive use parent scope. Is that what you're asking? I don't quite get your question... Commented Sep 12, 2014 at 15:44
  • Also the code in your link function is just a boolean expression. Did you mean to include that in an IF statement? Commented Sep 12, 2014 at 15:45
  • scope.status === 'undefined' <== doesn't do anything all by itself. What are you expecting? Commented Sep 12, 2014 at 15:45

4 Answers 4

66

The way to do this is to check for the existence of the attributes within the link function's attrs parameter, and assign this to variables within your directive's isolate scope.

scope:{},
link: function(scope, element, attrs){
  scope.status = 'status' in attrs;
},

This should work without having to use an if statement within your link function.

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

Comments

19

The way to do what you want is by looking at the attribute object in the link function:

link: 
  function(scope, element, attrs) {
    if("status" in attrs)
       //do something
  }

Comments

4

To Check for attributes when using angular 1.5+ components you can use the $postLink lifecycle hook and the $element service like this:

constructor(private $element) {}

$postLink() {
  if(!this.$element.attr('attr-name')){
    // do something
  }
}

Comments

1

Since the attrs value is type of javascript object. To check attribute existence we can also using hasOwnProperty() method instead in keyword.

So, it could be :

link: function(scope, element, attrs) {
  var is_key_exist = attrs.hasOwnProperty('status');//Will return true if exist
}

You can read further the difference between in keyword and hasOwnProperty() method at this link

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.