title: AngularJS dynamic required attribute in directive and form validation
body: <p>I have a directive that receives whether an element should be <strong>required or not from a REST api</strong>. Right now, I can't seem to get the form to invalidate when an attribute is set to required. </p>
  
  <p>So, in essence I'm able to dynamically add the 'required' attribute from the directive below, but it doesn't invalidate the form. Looking through chrome I see that, even though the required attribute exists, a required entry in the $error array doesn't  exist.</p>
  
  <pre><code>app.directive('requireiftrue', function ($compile) {
      return {
          require: '?ngModel',
          link: function (scope, el, attrs, ngModel) {
              if (!ngModel) {
                  return;
              }
  
              if(attrs.requireiftrue==="true"){
                  console.log('should require');
                  el.attr('required', true);
                  $compile(el.contents())(scope);
              }
              else{
                  console.log('should not require');   
              }
          }
      };
  });
  </code></pre>
  
  <p>Here's a <a href="http://jsfiddle.net/olingern/zsrfe513/" rel="nofollow">jsfiddle</a> to illustrate the problem. And, here's sample JSON returned from my rest API</p>
  
  <pre><code>{
      race: false,
      martialStatus: true,
  }
  </code></pre>
  
  <p><strong>EDIT:</strong> While the accepted answer got me up and running, I still had a good bit of finagling to do. </p>
  
  <p>Namely:
  1. Resolving a deferred promise to ensure that my form actually receives the required fields to validate
  2. observing my 'requireiftrue' attribute</p>
  
  <p><strong>My solution</strong></p>
  
  <p>module config:</p>
  
  <pre><code>function config($stateProvider) {
      $stateProvider
  
      .state('testState', {
          url: '/test/form',
          controller: 'TestCtrl',
          templateUrl: 'test/form/testForm.tpl.html',
          resolve: {
              formDefaultService: function getFormDefaults($q, dataservice) {
                  // Set up a promise to return
                  var deferred = $q.defer();
                  var myData = dataservice.getFormDefaults();
                  deferred.resolve(myData);
  
                  return deferred.promise;
                  //return 
              }
          },
  
          data: {
              pageTitle: 'Test Info'
          }
      });
  }
  </code></pre>
  
  <p>And, finally the directive / HTML that receives api data:</p>
  
  <p><strong>Directive:</strong></p>
  
  <pre><code>.directive('requireiftrue', function ($compile) {
      return {
          require: '?ngModel',
          link: function (scope, el, attrs, ngModel) {
              if (!ngModel) {
                  return;
              }
              attrs.$observe('requireiftrue', function(value){ 
                  if(value==="true"){
                      el.attr('required', true);
                      el.removeAttr('requireiftrue');
                      $compile(el[0])(scope);
                  }
              });
          }
      };
  });
  </code></pre>
  
  <p><strong>HTML:</strong></p>
  
  <pre><code>&lt;input max="40"
  requireiftrue={{defaults.validation.name}}
  validNumber
  id="name"
  name="name"
  type="text"
  ng-model="test.name"
  class="form-control"&gt;
  </code></pre>