Search code examples
facebookangularjsfacebook-comments

Facebook comment plugin Angularjs


I am facing a strange error while adding the facebook comment plugin in my AngularJS app. The simplified structure of the app page is

<html ng-app="myapp">
<head>
 ...
</head>
<body>
<div>
...
</div>
<div ng-view></div>
...
</body>
</html>

The page with fb comment box is loaded in ng-view. The structure of page that contains fb comment box is as follows

<div id="fb-comment-box>
 <div class="fb-comments" data-href="http://mydomain.com/page/{{ page.id }}" data-numposts="5" data-colorsheme="light"></div>
</div>

The page is angularjs scope variable which comes from controller. When i load this page in browser and do inspect element. It shows the correct page id i.e. data-href is

data-href = "http://mydomain.com/page/2"

But below the fb comment box, Facebook shows following error

Warning: http://mydomain.com/page/%7B%7B%20page.id%7D%7D is unreachable.

I can see the angularJS scope variable is not binding. Does anyone know how to solve this issue?


Solution

  • This is probably due to the fact that the FB functionality kicks in before Angular is able to change the data-href attribute.

    A directive seems like a good choice here:

    You basically need to create the comment-box after Angular can provide the correct URL.
    Because this involves asynchronous DOM manipulation, you need to use FB.XFBML.parse() to let FB process the comment-box once the data-href attribute is changed.

    The directive:

    .directive('dynFbCommentBox', function () {
        function createHTML(href, numposts, colorscheme) {
            return '<div class="fb-comments" ' +
                           'data-href="' + href + '" ' +
                           'data-numposts="' + numposts + '" ' +
                           'data-colorsheme="' + colorscheme + '">' +
                   '</div>';
        }
    
        return {
            restrict: 'A',
            scope: {},
            link: function postLink(scope, elem, attrs) {
                attrs.$observe('pageHref', function (newValue) {
                    var href        = newValue;
                    var numposts    = attrs.numposts    || 5;
                    var colorscheme = attrs.colorscheme || 'light';
    
                    elem.html(createHTML(href, numposts, colorscheme));
                    FB.XFBML.parse(elem[0]);
                });
            }
        };
    });
    

    The HTML:

    <div id="fb-comment-box" dyn-fb-comment-box
            page-href="https://example.com/page/{{page.id}}"
            numposts="5"
            colorscheme="light">
    </div>
    

    NOTE:
    The directive's scope will constantly watch for changes in the page-href attribute and update the comment-box. You can change this to suit your needs (e.g. also watch for changes in the other attributes or bind it once and stop watching).


    See, also, this short demo.