I am writing a directive in angularjs and get the above mentioned error. I am using the code from a book.
.directive('myFacebook', [function(){
return {
link: function(scope,element,attributes) {
(function(d) {
var js, id = 'facebook-jssdk',
ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {
return;
}
js = d.createElement('script');
js.id = id;
js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
// Initialize FB
window.fbAsyncInit = function() {
FB.init({
appId: 'xxxx', //birthday reminder
status: true, // check login status
cookie: true, // enable cookies to access the session
xfbml: false // parse XFBML
});
//Check FB Status
FB.getLoginStatus(function(response) {
xxxx
});
};
scope.username='';
},
scope: {
permissions: '@',
myFriends: '=friends'
},
controller: function($scope) {
$scope.loadFriends = function() {
FB.api('/me/friends?fields=birthday,name,picture', function(response) {
$scope.$apply(function() {
$scope.myFriends = response.data;
});
});
}
},
template:'Welcome {{username}}'
}}])
I get error at
$scope.$apply(function() {
$scope.myFriends = response.data;
});
The HTML code
<div my-facebook></div>
<h1> My Friend's Birthday Reminder</h1>
<div ng-repeat="friend in myFriends">
{{friend.name}}
</div>
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:
permissions
property the value of DOM attribute with the same namemyFriends
property and the parent scope's friends
propertySince 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-
anddata-
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>
I run to this same issue and for me the problem was upper case characters in DOM name.
<div my-facebook FRIENDS="friendList"></div>
did not work, but
<div my-facebook friends="friendList"></div>
worked. I spent a day working on this and found the solution by accident.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With