B4J Question [BANano] How to use the Google APIs

Mashiane

Expert
Licensed User
Longtime User
Hi there

I am just starting to explore the google api, these however dont seem to follow any approach im familiar with.

As an example..


The code in this file has scripts which call a method onload. How do I do something similar with BANano as I guess I have to call a sub on code?

B4X:
<script async defer src="https://apis.google.com/js/api.js" onload="gapiLoaded()"></script>
    <script async defer src="https://accounts.google.com/gsi/client" onload="gisLoaded()"></script>

Thanks in advance.
 
Solution
The key to incorperating someone else's code is trying to understand WHY they do certain things. Just doing a copy-and-paste of someones code is seldom the most omtimized solution in another environment.

Looking a the code, the writer tries to achieve two things:

1. Control the button visibility depending on the javascripts load finished
2. Loading the overall WebPage faster

This visibility issue can easily be done by using normal BANano code. Calling both methods in BANano_Ready can achieve the same thing. There is no need to use an onLoad in the script tag.

As for the speed, using defer/async can be faster than not using it, but it is also something you have to do VERY careful about, knowing ALL the javascript and html used...

walterf25

Expert
Licensed User
Longtime User
Hi there

I am just starting to explore the google api, these however dont seem to follow any approach im familiar with.

As an example..


The code in this file has scripts which call a method onload. How do I do something similar with BANano as I guess I have to call a sub on code?

B4X:
<script async defer src="https://apis.google.com/js/api.js" onload="gapiLoaded()"></script>
    <script async defer src="https://accounts.google.com/gsi/client" onload="gisLoaded()"></script>

Thanks in advance.
Maybe this will point you in the right direction.

This code is to use the oauth2 library to authenticate a user and retrieving the signed in email address.

Note that this example is for the abmaterial framework, but I'm pretty sure you can use it for Banano as well.

B4X:
page.AddExtraJavaScriptFile("https://apis.google.com/js/api.js")

and the script string is the following:

B4X:
    Dim script As String = $"
            var clientId = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com';
            var scopes = 'https://www.googleapis.com/auth/userinfo.email';
    
            gapi.load('auth2', function() {
                gapi.auth2.init({
                clientId: clientId,
                plugin_name: 'put anything here',
                scope: scopes
            });
            gapi.auth2.getAuthInstance().signIn().then(function(user) {
            var userEmail = user.getBasicProfile().getEmail();
            console.log('User Email: ', userEmail);
            b4j_raiseEvent('page_parseevent', {'eventname': 'page_signedinuseremail','eventparams':'email','email': userEmail});
            });
            });
            "$

Hope this helps.

Walter
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
The key to incorperating someone else's code is trying to understand WHY they do certain things. Just doing a copy-and-paste of someones code is seldom the most omtimized solution in another environment.

Looking a the code, the writer tries to achieve two things:

1. Control the button visibility depending on the javascripts load finished
2. Loading the overall WebPage faster

This visibility issue can easily be done by using normal BANano code. Calling both methods in BANano_Ready can achieve the same thing. There is no need to use an onLoad in the script tag.

As for the speed, using defer/async can be faster than not using it, but it is also something you have to do VERY careful about, knowing ALL the javascript and html used in your project. Using it wrongly can easily result in a broken project. In such a small project as this, and without using any external frameworks, it is something you can control.

I'm not going to explain what async/defer does (google it) and as I will show further this is not even needed in BANano so this could only cause confusion.

A speed analysis:

Without async/defer/onLoad, setting the JavaScript after the two <script src="http..."> tags and calling both the gapiLoaded and gisLoaded methods at the very end. So, doing it the 'normal way'.

1686229134725.png


With async/defer (as in the example):

1686229005093.png


You can notice the last two numbers, especially the DOMContentLoaded is smaller (25ms vs 110ms) in the one without async/defer, Load is almost the same (349ms vs 317ms).

Same project, in BANano with the build-in Dynamic JavaScript Loading (is automatic, nothing you have to do for this). Because of the way BANano constructs the loading of resources, the app code is always loaded AFTER the two scripts . This avoids any possible conflict a wrongly constructed async/defer could cause.

1686229622795.png


So, BANano uses an even smarter way to load resources faster: Dynamic JavaScript Loading. Even dispite using an extra UI framework like BANanoSkeleton, Load is much faster (111ms vs 317ms) and DOMContentLoaded (26ms vs 25ms) is on par with using async/defer.

Of course because BANanoSkeleton is highly optimized (each component is carefully manually optimized to be very lightweight) and written using as much Vanilla Javascript as possible. As BANano can strip out dead (unused) code (up to method level!), the size of resources that have to be interpreted by the browser is kept to an absolute minimum.

Our BANano PWAs using BANanoSkeleton can easily compete with their native counterparts and have no need for such contructions.

Alwaysbusy
 
Upvote 1
Solution

Mashiane

Expert
Licensed User
Longtime User
Calling both methods in BANano_Ready can achieve the same thing. There is no need to use an onLoad in the script tag.
Cool, this is exactly the clarity I need in terms of doing things the BANano way.

Awesome, I will give the google guys code a try and see. I want to write the code the BANano way without having to inject pure javascript.
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
I don't know what deadline you have, but I'm working on new stuff in BANano that will allow mixing B4J syntax and JavaScript even more.

Example now in BANano:
B4X:
Dim D3 as BANanoObject
D3.Initialize("D3")
Dim width as Double = 500
Dim height as Double = 400
Dim svg As BANanoObject
svg = D3 _
            .RunMethod("select", ID) _
            .RunMethod("append", "svg") _
            .RunMethod("attr", Array("viewbox", Array(-width/2, -height/2, width, height))) _
            .RunMethod("attr", Array("width", "100%")) _
            .RunMethod("attr", Array("height", "calc(100vh - 180px)")) _
            .RunMethod("style", Array("font", "12px sans-serif"))

Same but with new BANano JS() method and special smart string variables @${} :
B4X:
Dim D3 as BANanoObject
D3.Initialize("D3")
Dim width as Double = 500
Dim height as Double = 400
Dim svg As BANanoObject
svg = D3.JS($"
            .select(@${ID})
            .append("svg")
            .attr("viewbox", @${-width/2}, @${-height/2},@${width}, @${height})
            .attr("width", "100%")
            .attr("height", "calc(100vh - 180px)")
            .style("font", "12px sans-serif")
            "$)

This mix will even work on line level:
B4X:
Dim g As BANanoObject
g = svg.RunMethod("append", "g")

Dim zoomed As BANanoObject
zoomed = BANano.JS($"function zoomed({transform}) {"$)
                      g.JS($".attr("transform", transform);"$)
                      If g.ClientWidth = 100 Then
                            g.ClientLeft = 15
                            g.ClientTop = 0
                      End If            
        BANano.JS($"}"$)

zoomed.Execute(BANano.JS("d => `translate(${d.x},${d.y})`"))

Stuff that most users will never encounter when making a BANano WebApp but that can be useful to speed up writing libraries for the more advanced users with good JavaScript knowledge.

Alwaysbusy
 
Upvote 0

Mashiane

Expert
Licensed User
Longtime User
I'm working on new stuff in BANano that will allow mixing B4J syntax and JavaScript even more.
Wow.

Stuff that most users will never encounter when making a BANano WebApp but that can be useful to speed up writing libraries for the more advanced users
Just checked the code, well its advanced for my head, i guess for things like react / node etc could prove useful.

Amazed, wonderful, congrats, this is becoming extremely powerful, yet im still at surface knowledge.

Thank you so much again.

PS: Just satisfying my curiosity about GAPI, would love to explore it more.

I wish you could give us the latest beta to play with. Please, ;)
 
Upvote 0
Top