FB Like button shows up only once - on first load of my AngularJS view
Asked Answered
F

7

7

I am trying to place the FB like button on my single page site built on Angular JS. The like button has to be displayed on a view (different than the index.html) displayed by a controller. But the like button shows up only for the first time I load that particular view. The button do not show up if I come back after visiting another view. Below is the code which loads FB SDK in the controller for the view -

(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/all.js#xfbml=1"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));

index.html has the following code-

<body ng-controller="mainController">

<div id="fb-root">

myView.html

<div class="fb-like" data-href="mySite.com/{{ProductID}}" data-> layout="standard" data-action="like" data-show-faces="false" data-share="true">

I have tried various methods like using the FB.XFBML.Parse(), removing the script tag for FB sdk and adding it in every load(with the hope that it will work like the first time), tried using the directives, placing the fb-root div in various views and now I am clueless :|

I feel the issue is with loading or refreshing the SDK on revisiting the view but I am not sure.

Will appreciate any input which will help me move forward and please let me know if you need any more info.

Thanks, Sam.

Forsworn answered 2/12, 2013 at 21:50 Comment(0)
P
11

I believe I found the solution.

Set in the begining of your widget script FB = null; and remove the "if (d.getElementById(id)) return;"

It should look like this:

FB = null;
(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/pt_BR/all.js#xfbml=1";
    fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
Preterite answered 30/12, 2013 at 15:48 Comment(4)
It works for me now :) Maybe I did it wrong the first time. Thanks a lot! Now I can get rid of the iframe widgetForsworn
Please make sure that <div id="fb-root"></div> is inside the partial loaded by ng-view, otherwise I had problems getting it working.Aforetime
IMO, this might work for some cases but it's not universal answer. Why? for embedded videos, it incorrectly calculates width-height and your video would exist but it won't be visible due to 0px height/width. https://mcmap.net/q/1401679/-fb-like-button-shows-up-only-once-on-first-load-of-my-angularjs-viewStlaurent
FB = null just resets the facebook script. That is not optimal because it reloads the whole facebook js once again while it only has to force facebook to reprocess the dom tree. The correct answer is below, you have to just add if (window.FB) window.FB.XFBML.parse().Doubledealing
S
8

The accepted answer given by user2912405 it's perfect. I just wanted to add that if you are using AngularJS

You should use:

$scope.$on('$viewContentLoaded', function() {
    (function(d, s, id) {
        FB = null;
        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/all.js#xfbml=1&appId=204269043065238";
        fjs.parentNode.insertBefore(js, fjs);
      }(document, 'script', 'facebook-jssdk'));
});

To get the buttons re-loaded every time we change the view, for example when we follow a link

Sheepskin answered 22/4, 2014 at 21:5 Comment(3)
When I add more items by AngularJS (ng-Repeat), The facebook like button (html5) won't work... Any way to run the init again?Yamamoto
You mean you have one like button for every item in the ng-repeat?Sheepskin
I got an error when using this. It's "Error: assignment to undeclared variable FB". How can I fix it?Roubaix
C
2

accepted answer worked for me, after much trial an error (fb root was ommitted). here is the full snippet to include in your view:

<div id="fb-root"></div>
<script>
    FB=null;
    (function(d, s, id) {
        var js, fjs = d.getElementsByTagName(s)[0];
        js = d.createElement(s); js.id = id;
        js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&appId=xxxxxxxxx&version=v2.0";
        fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));</script>

also make sure to delete any code from index page

Canicula answered 23/8, 2014 at 2:3 Comment(0)
O
1

The accepted answer did not work for me on my Angular 5 project.

Adding this to my component class worked:

ngOnInit() {
    if (window['FB']) {
        window['FB'].XFBML.parse();
    }
}
Ortrud answered 10/1, 2018 at 22:35 Comment(0)
L
0

Personally, I ended up with something like this. I have a component in angular 1.5. In index file, there is classic markup from documentation and inside the component

this.$onInit = function() {
    var facebookButtonEl = $element[0].querySelector('.fb-share-button');

    if (facebookButtonEl)
    angular.element(facebookButtonEl)
        .attr('href', $location.absUrl())
        .attr('data-href', $location.absUrl());

    if (window.FB) {
        window.FB.XFBML.parse();
    }
}

The important part is the FB.XFBML.parse() which envokes re-rendering of the button

Lusatian answered 26/7, 2016 at 11:29 Comment(2)
This works but for some reason angular is telling me that XFBML is undefined Any ideas why this is or how I can stop the error message?Kimi
Nevermind I added the window.FB and it worked completelyKimi
S
0

IMHO, the accepted answer is not good answer. Following reasons:

  • You would end up inserting script multiple times.
  • window.FB = null is better syntax, instead of FB = null
  • If script already exists then don't add-fetch script again. Instead, manually do window.FB.XFBML.parse();.

    (function(d, s, id) {
        var js, fjs = d.getElementsByTagName(s)[0];
        if (d.getElementById(id)) {
           window.FB.XFBML.parse(); // Helps to identify FB elements again.
           return;
        }
        js = d.createElement(s); js.id = id;
    
    
        js.src = "https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.6"; // Put your Latest version here.
        fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));
    

FB.XFBML.parse

Stlaurent answered 20/5, 2018 at 13:0 Comment(0)
I
0

For those using opt-in cookie consent (for GDPR Law for example) and need to active for the first time programmatically the fb plugin:

var loadFB = (function (d, s, id) {
  //- call this function after receiving consent
  return function loadFB() {
    var js, fjs = d.getElementsByTagName(s)[0];
    if (window['FB']) {
      window['FB'].XFBML.parse();
      return;
    }

    js = d.createElement(s);
    js.id = id;
    js.src = 'https://connect.facebook.net/fr_FR/sdk.js#xfbml=1&version=v3.0';
    fjs.parentNode.insertBefore(js, fjs);
  }
}(document, 'script', 'facebook-jssdk'));

In app.component.ts :

const onNavigationEnd = this.router.events.pipe(
  filter(event => event instanceof NavigationEnd),
  map((event: NavigationEnd) => {
    // ccService is the cookieConsentService
    if (this.ccService.hasConsented()) {

      // Set Google Analytics
      ga('set', 'page', event.urlAfterRedirects);
      ga('send', 'pageview');

      // Set Facebook sdk
      loadFB();

    }
  })
);
Ibadan answered 23/6, 2018 at 10:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.