Element directives broken?

Hi guys, I’m pretty happy that we can do Angular in Meteor, ionic in particular, but also for webapps.

While I was working in my first Meteor-Angular webapp, I’ve found myself trying to refactor my first element directive (restricted: 'E') so the html can be clean and expressive.

Do they work?

As a sanity check I’ve created a new project in a new folder and followed this tutorial today http://www.angular-meteor.com/tutorials/socially/angular1/adding-removing-objects-and-angular-event-handling and at the end of the Step 3 you should see rendering your brand new componentized element directive. But it renders nothing. Inspecting the html reveals the element with the right tag is there but nothing is there…

You must be kidding… Just when writing this look at what I’ve found:

This makes it all work as expected:

angular.module('socially').directive('partiesList', function () {
  return {
    restrict: 'E'
    , templateUrl: 'client/parties-list.html'
    , controllerAs: 'partiesList'
    , controller: function ($scope, $reactive) {

        $reactive(this).attach($scope);

        this.helpers({
          parties: function () {
            return Parties.find({});
          }
        });
    }
  }
});

But this one renders nothing:

angular.module('socially').directive('partiesList', function () {
  return {
    restrict: 'E'
    , templateUrl: 'client/parties-list.html'
    , controllerAs: 'partiesList'
    , controller: ($scope, $reactive) => {

        $reactive(this).attach($scope);

        this.helpers({
          parties: function () {
            return Parties.find({});
          }
        });
    }
  }
});

I guess one has to be extra careful with => notation?

Note that arrow functions in ES2015 exist specifically to change the function of this. If you want fancy syntax, I would suggest using object method shorthand, like so:

angular.module('socially').directive('partiesList', function () {
  return {
    restrict: 'E'
    , templateUrl: 'client/parties-list.html'
    , controllerAs: 'partiesList'
    , controller($scope, $reactive) {

        $reactive(this).attach($scope);

        this.helpers({
          parties: function () {
            return Parties.find({});
          }
        });
    }
  }
});

Arrow functions take the this from outside the function, so this inside the arrow function doesn’t know anything about helpers, or reactivity, or the directive. It probably refers to window.

1 Like

You’re right @sashko, thanks for exposing the exact reason and a good alternative.