Error: [$compile:nonassign] Expression 'undefined' used with directive 'myFacebook' is non-assignable

My solution was harder to find out here, but easier to implement. I had to change it to the equivalent of (Note that the question mark makes the attribute optional. Prior to 1.5 this apparently wasn't required).

scope: {
    permissions: '@',
    myFriends: '=?friends'
}

The problem is that you are not defining the attribute friends in the directive element <div my-facebook></div>.

When you define the directive's scope like this:

scope: {
    permissions: '@',
    myFriends: '=friends'
}

You are basically saying:

  • Bind to the local scope's permissions property the value of DOM attribute with the same name
  • Set up bi-directional binding between the local scope's myFriends property and the parent scope's friends property

Since you are not defining the attribute friends in the DOM, Angular cannot create the bi-directional binding and throws the error. More information here.

Define the friends attribute on your DOM and it should fix the problem:

<div my-facebook friends="friendList"></div>

And, for example, on the controller:

app.controller('Ctrl', function($scope) {
  $scope.friendList = [];
});

Not a direct answer to OPs question, but this just happened to me so for anyone else that might Google this error in the future. This is similar to JohnP's answer.

This error can also appear if you have a camelCase attribute in your directive.

So if you have:

<div my-facebook myFriends></div>

It will throw the error.

This is because (taken from the angular documentation):

Angular normalizes an element's tag and attribute name to determine which elements match which directives. We typically refer to directives by their case-sensitive camelCase normalized name (e.g. ngModel). However, since HTML is case-insensitive, we refer to directives in the DOM by lower-case forms, typically using dash-delimited attributes on DOM elements (e.g. ng-model).

The normalization process is as follows:

Strip x- and data- from the front of the element/attributes.

Convert the :, -, or _-delimited name to camelCase.

so <div my-facebook myFriends></div>

will need to become <div my-facebook my-friends></div>