Facebook Comments Plugin not displaying in AngularJS
Asked Answered
C

2

3

SEE UPDATE AT BOTTOM OF THIS POST

I am trying to implement a Facebook comments box in an ng-repeat and am having issues with it displaying.

In Chrome it doesn't display until I click the refresh button, whereas in IE10 I can not get it to display at all.

My (simplified) index page:

<!doctype html>
<html lang="en" data-ng-app="eatsleepcode">
    <head>
        <title data-ng-bind="pageTitle">&lt;eat-sleep-code /&gt;</title>
        <meta charset="utf-8" />
            <base href="/">
        <link rel="stylesheet" href="/style/jquery-ui.min.css" />
        <link rel="stylesheet" href="/style/bootstrap.min.css" />
        <link rel="stylesheet" href="/style/bootstrap-theme.min.css" />
        <link rel="stylesheet" href="/style/en-us.css" />
    </head>
    <body>
        <div class="container-fluid">
            <div class="col-lg-8 page-content" id="content" data-ng-view>
            </div>
            <div class="col-lg-4 page-content">
                </div>
        </div>
        <footer id="footer">
            <div class="container-fluid">
            </div>
        </footer>
        <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
        <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.10/angular.min.js"></script>
        <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.10/angular-resource.min.js"></script>
        <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.10/angular-route.min.js"></script>
        <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.10/angular-sanitize.min.js"></script>
        <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.10/angular-animate.min.js"></script>
        <script type="text/javascript" src="/scripts/xml2json.min.js" ></script>
        <script type="text/javascript" src="/scripts/bootstrap.min.js"></script>
        <script type="text/javascript" src="/scripts/app.js"></script>
        <script type="text/javascript" src="/scripts/jquery.validate.min.js" defer="defer"></script>        
        <script type="text/javascript" src="/scripts/render.min.js" defer="defer"></script>     
        <script type="text/javascript" src="/scripts/repo.min.js" defer="defer"></script>
        <div id="fb-root"></div>
        <script type="text/javascript">
            (function(d, s, id) {
              var js, fjs = d.getElementsByTagName(s)[0];
              if (d.getElementById(id)) return;
              js = d.createElement(s); js.id = id;
              js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&appId=1442336282690482&version=v2.0";
              fjs.parentNode.insertBefore(js, fjs);
            }(document, 'script', 'facebook-jssdk'));
        </script>
    </body>
</html>

My view:

<div class="blog-main">
    <article class="blog-post" data-ng-if="article.id == post || post===NULL" data-ng-repeat="article in data.blog.article | orderBy:'createdate':true | slice:currentPage*pageSize:currentPage+1*pageSize" itemscope itemtype="http://schema.org/BlogPosting">
        <h2 class="blog-post-title" itemprop="headline">
            <a href="http://eat-sleep-code.com/#!/blog/{{article.id}}" title="Permalink to {{article.title.__cdata}}" itemprop="url">{{article.title.__cdata}}</a>
        </h2>
        <span class="blog-post-meta">Posted on <time datetime="{{article.createdate | date:'yyyy-MM-dd'}}">{{article.createdate | date:'MMMM dd, yyyy h:mma'}}</time> by <span itemprop="author">{{article.author}}</span></span>
        <div class="blog-post-content-wrapper">
            <div class="blog-post-content" ng-bind-html="article.content.__cdata" itemprop="text">
                {{article.content.__cdata}}
            </div>
        </div>
        <div data-ng-if="article.id == post">
            <div class="fb-comments" data-href="http://eat-sleep-code.com/#!/blog/{{article.id}}" data-numposts="5" data-colorscheme="light" data-width="100%"></div>
            <br />
            <a href="/#!" class="btn btn-default btn-sm blog-button-back"><span class="glyphicon glyphicon-chevron-left blog-button-back-icon"></span> Back</a>
        </div>  
    </article>

    <div data-ng-if="numberOfPages > 1">
        <button type="button" class="btn btn-default btn-sm blog-button-older" data-ng-disabled="currentPage == 0" data-ng-click="currentPage=currentPage-1"><span class="glyphicon glyphicon-chevron-left blog-button-older-icon"></span> Older Posts</button>
        <button type="button" class="btn btn-default btn-sm blog-button-newer" data-ng-disabled="currentPage >= numberOfPages - 1" data-ng-click="currentPage=currentPage+1">Newer Posts <span class="glyphicon glyphicon-chevron-right blog-button-newer-icon"></span></button>
    </div>
</div>

I found this issue: Facebook comment plugin Angularjs but mine appears to be different, because when I view the current elements, I see that the data-href is populated correctly:

<div class="fb-comments" data-href="http://eat-sleep-code.com/#!/blog/2" data-numposts="5" data-colorscheme="light" data-width="100%"></div>


UPDATE:

I updated the line in the view to this:

<div class="fb-comments" dyn-fb-comment-box page-href="http://eat-sleep-code.com/#!/blog/{{article.id}}" data-numposts="5" data-colorscheme="light" data-width="100%"></div>

I added the following directive, and now the comments box is displaying. However, the data-width attribute is now being ignored. The comments box is rendering at the default 550px width.

app.directive('dynFbCommentBox', function () {
    function createHTML(href, numposts, colorscheme, width) {
        return '<div class="fb-comments" ' +
                       'data-href="' + href + '" ' +
                       'data-numposts="' + numposts + '" ' +
                       'data-colorsheme="' + colorscheme + '" ' +
                       'data-width="' + width + '">' +
               '</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';
                var width = attrs.width || '100%';
                elem.html(createHTML(href, numposts, colorscheme, width));
                FB.XFBML.parse(elem[0]);
            });
        }
    };
});
Camorra answered 6/6, 2014 at 16:10 Comment(5)
Maybe try wrapping the facebook code in a setTimeoutAdi
Yes, the line FB.XFBML.parse(elem[0]); definitely needs to be wrapped into setTimeout or $timeout function !!!Manure
why does it need a timeout @Manure ?Steward
Maybe because of Angular digest cycle?Manure
Thank you so much bro!!!Evanthe
J
3

You would need to make a directive that watches the data-href attribute as suggested in the (essentially same) issue with flash in https://mcmap.net/q/1924361/-angular-directive-to-display-flash-via-lt-object-gt-tag-causes-flash-to-attempt-to-load-expression and also in the post you are pointing to yourself with the facebook link. The reason is still the same; angular takes some time interpolate the values between the interpolation symbols and therefore the facebook sdk just "fires" on the data that is there, which essentially will be http://eat-sleep-code.com/#!/blog/{{article.id}} because it is not a part of angular's internal loop.

There are also many other articles that deals with the issue of loading images, as the browser will try to fetch all images using the src attribute when it encounters one, also happing before the real src value has been interpolated. Therefore, there are are directives made by the core angular team such as ng-src that deals with such common usecases, but on this one you would have to do it as the post you are linking to describes.

Juicy answered 6/6, 2014 at 16:29 Comment(8)
See the update I put in my original post above. It is working except the data-width="100%" is not being honored.Camorra
Have you checked this: #10862756Juicy
Tried both. The first answer did nothing. The accepted answer broke the page. Instead of the facebook control ONLY 'data-width="100%">' was written to the page.Camorra
I am not a computer atm to help, but the best approach would then be to either find whats causing the problem, or hack it by inspecting the DOM and applyint the correct css brute-force-style. Let me know how it goes, if not i will look at when im back at my desk :)Juicy
Oh it's going to be fun. It appears that FB has a bunch of nested items, including content inside an iframe -- :-( --, all with a width specified inline of 550px.Camorra
Ok, I did notice an extra bracket. Now it's working in Chrome, Firefox, Safari, and IE11. But it's now displaying at 300px wide in IE10? Weird!Camorra
Weird. First, I would recommend checking if this is a IE10 specific issue. Maybe force a style using this approach if so: css-tricks.com/override-inline-styles-with-cssJuicy
I can't really figure it out. If I set the iframe to 100% width -- so it could be responsive/fluid -- the iframe completely disappears in IE10. You can see the page here. Right now its back to its default (no forced styling).Camorra
K
0

i was trying with protocol free url for data-href attr; it didn't work; once i added http it worked - possibly that could be a cause.

Kalimantan answered 23/7, 2015 at 7:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.