0

I am attempting to pass down attributes returned from a MongoDB query to a directive in Angular, but for some reason it will not pass down an "_id" attribute. When I view the records returned in the parent's $scope, I can see that each object does in fact have an "_id". However when I go to inspect the $scope of the directive I am attempting to render, I can see that it has every attribute besides "_id".

My parent template code:

<div id=cards>
    <div ng-repeat='card in cards' class='card'>
        <card-directive 
            _id={{card._id}} attack={{card.attack}} cost={{card.cost}}
            health={{card.health}} img={{card.img}} name={{card.name}}
            hero={{hero}} rarity={{card.rarity}} type={{card.type}}
            class={{hero}} add={{add}} faction={{card.faction}} > 
        </card-directive>
    </div>
</div>

My directive code:

function cardDirective() {
    return {
        restrict: 'E',
        scope: {
            '_id': '@',
            'img': '@',
            'attack': '@',
            'cost': '@',
            'health': '@',
            'name': '@',
            'rarity': '@',
            'type': '@',
            'hero': '@',
            'add': '@',
            'faction': '@'
        },

Is there something special about including an attribute that begins with an underscore?

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Ben Melito
  • 131
  • 2
  • 12
  • You don't use it like this: `_id={{card._id}}`, you use it like this: `_id="{{card._id}}"`. Also, for the attribute name beginning with underscore, check this https://stackoverflow.com/a/79022/4488121 – lenilsondc Aug 30 '17 at 20:12
  • AngularJS directives normalize attributes with underscores to camelCase. For more information, see [AngularJS Developer Guide - Directive Normalization](https://docs.angularjs.org/guide/directive#normalization). – georgeawg Aug 31 '17 at 11:08

2 Answers2

2

It should have worked, only wrap your attribute value with "(quotes)

Rather than passing each value inside attribute, you could consider passing whole card object to directive.

<div id=cards>
    <div ng-repeat='card in cards' class='card'>
        <card-directive my-card="card"></card-directive>
    </div>
</div>

Directive

function cardDirective() {
    return {
        restrict: 'E',
        scope: {
            'myCard': '<'
        },

So inside directive you could easily access value inside card object and < ensure one way binding. You could use {{myCard._id}} for using _id.

Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
  • It still isn't working with the quotes for some reason, but I like the idea of passing an object. Is there anything special I need to do to access it as an object rather than a string? – Ben Melito Aug 30 '17 at 20:37
  • @BenMelito no, `<` (one way binding) will pass object to directive automatically. you could easily access props from object. – Pankaj Parkar Aug 30 '17 at 20:50
  • Can you also post the markup of the directive's template? Maybe there's something wrong there. – Bruno Poeta Aug 31 '17 at 04:53
0

AngularJS is normalizing the attribute _id to Id with a capital I.

For more information, see AngularJS Developer Guide - Directive Normalization.

angular.module("app",[])
.directive("customDirective", function() {
  return {
    template: `Id={{Id}}`,
    link: function(scope, elem, attrs) {
      scope.Id = attrs.Id;
      console.log("Id=",attrs.Id);
    }
  }
})
<script src="//unpkg.com/angular/angular.js"></script>
  <body ng-app="app">
    <div custom-directive _id=99></div>
  </body>
georgeawg
  • 48,608
  • 13
  • 72
  • 95