Verifying the presence of Angular loading Google (or other) APIs, or tips on preventing share buttons from disappearing

Having a bit of an issue here, actually, make that four issues, all related (or so I think). Tried using the google, twitter, whatsapp, and facebook API to add share buttons. They come nicely packaged and are easy to implement on the webpage, serving their purpose perfectly.

The problem lies in the fact that these scripts are not designed for angular. From what I gathered, the scripts load and wait for the DOM to be ready before looking for the elements they need to replace – such as divs and buttons. In my case, it looks something like this:

<a href="whatsapp://send" data-text="Unbrand: the webpage you need" data-href="http://unbrand.me/share/whatapp" class="wa_btn wa_btn_s" style="display:none; margin-bottom: 8px;">Share</a>
            <a href="https://twitter.com/share" style="margin-bottom: 8px;" class="twitter-share-button" data-url="http://unbrand.me/share/twitter" data-text="UnBrand - Tailored clothes just for you" data-mobile-iframe="true" data-via="unbrand_me" data-related="unbrand_me" data-hashtags="unbrand_me">Tweet</a>
            <div class="fb-share-button" style="margin-bottom: 8px;" data-href="http://unbrand.me/share/facebook" data-layout="button_count" data-mobile-iframe="true"></div>
            <div class="g-plus" style="margin-bottom: 8px;" data-action="share" data-annotation="bubble" data-href="http://unbrand.me/share/google"></div>
        </md-fab-actions>

I suspect that when these scripts scan the DOM, angular hasn't fully loaded the elements, at least most of the time. As a result, the required divs aren't found, the script assumes its task is complete, and angular generates normal links or divs instead. This is my assumption based on some research, like this thread on Google Signin button in AngularJS issues.

I came across an interesting solution in one particular thread – the idea of creating a watcher to monitor changes to the object. So, I added the following snippet to the controller handling that section of the page:

  $scope.$watch('gapi', function(newValue,oldVale){
        if(newValue !== oldVale){
            if(gapi){
                console.log("GAPI loaded")
                gapi.share.render('shareButton',
                    {
                        'onsuccess': $scope.onSuccess,
                        'onfailure': $scope.onFailure,
                        'scope':'https://www.googleapis.com/auth/plus.login'
                    }
                );
            }
        }
    });

I'm not entirely sure if `gapi.share.render` is a valid function of `gapi`, but my current struggle is that the watcher doesn't seem to trigger. My intention was to identify a key function in each of the JavaScript files and have the watcher monitor it, but so far, no success with the above code.

Am I overlooking something obvious here?

Oh, by the way, here's the API I'm utilizing:

<script src="https://apis.google.com/js/platform.js" async defer></script>

Answer №1

==================== This code had issues when used online, worked fine on my local machine only =====================

Alright, so this solution may not be the most elegant one out there, but it gets the job done, or at least better than before. I load the scripts during Angular startup in a .run function. As mentioned, it works, even though it might not look pretty :)

Also, it includes loading of Facebook, Twitter, Google, and WhatsApp APIs; feel free to remove any that are not needed

.run(['$rootScope', '$window',
    function($rootScope, $window) {

        $rootScope.user = {};

        $window.fbAsyncInit = function() {
            // Function executed upon SDK load

            FB.init({

                /*
                 The app id of the web app;
                 Visit Facebook App Dashboard
                 (https://developers.facebook.com/apps/) to register a new app
                 */

                appId: 'WOULDN't YOU LIKE TO KNOW',

                /*
                 Adding a Channel File improves javascript SDK performance
                 by addressing cross-domain communication issues in specific browsers
                 */

                channelUrl: 'app/channel.html',

                /*
                 Set if you want to check authentication status
                 at app start up
                 */

                status: true,

                /*
                 Enable cookies to allow server session access
                 */

                cookie: true,

                /* Parse XFBML */

                xfbml: true
            });

        };

        (function(d){
            // Load Facebook JavaScript SDK

            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));

        !function(d,s,id){
            var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';
            if(!d.getElementById(id)){js=d.createElement(s);
                js.id=id;
                js.src=p+'://platform.twitter.com/widgets.js';
                fjs.parentNode.insertBefore(js,fjs);
            }}(document, 'script', 'twitter-wjs');

        !function(d,s,id){
            var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';
            if(!d.getElementById(id)){js=d.createElement(s);
                js.id=id;
                js.src='https://apis.google.com/js/platform.js';
                fjs.parentNode.insertBefore(js,fjs);
            }}(document, 'script', 'gapi-wjs');
        
        if(typeof wabtn4fg==="undefined") {
            wabtn4fg=1;
            h=document.head||document.getElementsByTagName("head")[0],s=document.createElement("script");
            s.type="text/javascript";
            s.src="http://unbrand.me/bower_components/whatsapp-sharing/dist/whatsapp-button.js";
            h.appendChild(s)}

    }])

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issues with Toggling Visibility in HTML, CSS, and Javascript

Currently, I am working on a website and following a tutorial called "Creating Slideshow using HTML, CSS, and Javascript" by W3Schools. In the project, I want to hide the thumbnail images located at the bottom and the navigation arrows initially and have t ...

Creating TypeScript domain objects from JSON data received from a server within an Angular app

I am facing a common challenge in Angular / Typescript / JavaScript. I have created a simple class with fields and methods: class Rectangle { width: number; height: number; area(): number { return this.width * this.height; } } Next, I have a ...

Guide on capturing an image of a specific div using JavaScript

Currently working on an interactive "HTML Quiz" that operates solely on JavaScript - it's pretty impressive! Upon completion, a results box will appear displaying time taken, percentage score, and number of correct answers out of 10. I envision addin ...

The essential information for the data confirmation should consist of either the name or value of the selected

I am looking to incorporate dynamic content into a data confirmation message that appears when the user clicks on submit. In my views, I have: <div class="form-check"> <input class="form-check-input" type="radio" na ...

Unfortunately, we encountered an AJAX error while trying to access data from the website datatables.net. You can find

I'm currently working on adding data to a datatables.net datatable using a JSON response, following the example provided here. To achieve this, I am making use of an AJAX call to fetch a JSON response from a database. After obtaining the data, I uti ...

What is the best way to combine two JSON objects?

Item A: var item1 = { "roleid": "001", "techid": "001", "role": "WEB DEVELOPER", "tech": "JAVASCRIPT", "experience": [], "certifications": [], "gender": ["Male"], "awards": [], "min_experience_years": "4", "max_expe ...

I am facing an issue where my Popover functions correctly when elements are added using HTML, but not when they are dynamically created

I'm currently working on a method to incorporate multiple popovers that have a similar appearance to the following: The screenshot of my first JsFiddle project (click to view) The initial progress I've made can be seen in my first JsFiddle, acc ...

What is the most efficient method for defining a string structure in TypeScript?

Consider the following example of a JavaScript object: const myObject = { id: 'my_id', // Base value which sets the structure for the following values (always pascal case). upperID: 'MY_ID', // Uppercase version of `id`. camel ...

I encountered an issue with loading an array from session storage in Java Script

I am struggling to restore and reuse a created array in HTML. I attempted using JSON, but it was not successful for me. In the code below, I am attempting to reload items that were previously stored in an array on another page. However, when I try to loa ...

The creation of a Firebase user account with the specified email and password

I'm currently facing an issue while creating a new user with email and password using firebase authentication. The problem arises when I try to access the displayName from the returned async call before the updateProfile function, as it returns a null ...

Servlet question: What causes the XMLHttpRequest responseText to consistently appear empty?

I've been going crazy trying to figure out how to solve this issue. I have a servlet deployed in Tomcat running on localhost:8080 that looks like this: @WebServlet(urlPatterns = { "/createcon" }, asyncSupported = true) public class CreateCon extends ...

You won't be able to view over 15 KML layers on a page that relies on Google Maps API

I've encountered an unusual issue: I need to create multiple KML layers from separate KML files and display them on a single map window. The number of files ranges from just a couple to less than fifty. Currently, my code works perfectly when given 1, ...

How can you use yargs (npm package) to generate an error message when a command is not recognized?

Is it possible to have yargs with 2 commands? yargs .command('test-all','',handler) .command('test-file','',handler) .argv When the user inputs: node myapp.js other-command No error is thrown by yargs. What steps s ...

Unable to retrieve information from the API despite successfully establishing a connection

I have been attempting to establish a connection between backend Laravel and frontend AngularJS using an API and AJAX $http method. The API connection works fine, but I am facing an issue where the data is not displaying in the ng-repeat method. I am unsur ...

AngularJS relies heavily on the concept of internationalization, commonly referred

I18n key: "step1.download":"{{n0}} Get {{n1}} More content." Within my website: <span translate=step1.download translate-values="{ n0: '{{info0}}', n1: '{{info1}}'}"></span> Within my application logic: $scope.download ...

Erase every class within one second using only Pure Javascript

After trying to remove all classes after a second with no success, I attempted the code below: function copyLink() { var text = document.getElementsByClassName("text"), len = text.length; for(i = 0; i < len; i++) { text[i].classList.ad ...

Determine the number of items (within an array) that were created within the past few days, weeks, and months leading up to the 'current time'

Having an array filled with objects containing timestamps: Here is a glimpse of the data: const dataList = [ { _id: "602102db3acc4515d4b2f687", createdDt: "2021-02-08T09:22:35.000Z", }, { _id: "6021024da706a260d89 ...

The current Webpack configuration for production fails to account for importing CSS files

I am struggling to figure out how to properly load a static site that is not located in the root folder: let HWPTest = new HtmlWebpackPlugin({ template: __dirname + "/src/artists/test.html", filename: 'artists/test.html', favicon: &apos ...

How to fetch and display images using Vue.js with Axios and a web API

I have managed to successfully upload an image using axios and can preview it in Postman. However, I am unsure of how to proceed with rendering the image in vuejs. Implementing the Get Method: public HttpResponseMessage FetchImage(int id) { ImageServ ...

Suggestions for automatically adjusting the URL based on the browser's geographical location in Asia?

Is there a way to achieve the following scenario? I am looking to update the URL if the user's browser is from Asia. For example, if I visit a URL with the domain my.XXX.com, the application will detect the browser's location and automatically ch ...