They can not in pure BANano (the Browser side). They can on the server side (BANanoServer project).if some of the B4J libraries can be used with BANano
Hey Ilan, thanks, will really appreciate it if you could take a look, i know is a lot to ask but seems to me we are lacking this type of functionality, personally i am not very familiar with either javascript or web apps, I have a need to build something at work, i have been leveraging the power of B4x altogether here at work so far everyone is very amazed at how much can be accomplished with it, would hate to let my team down and not be able to complete this task.They can not in pure BANano (the Browser side). They can on the server side (BANanoServer project).
I assume this has something to do with your other node.js question? I'll try to get something setup on my machine on Monday so I can try if BANano does work with node.js.
Alwaysbusy
...google cloud APIs...
Just a quick update for those following this post, based on the information provided by @fredo I was able to do the following:If I understand it correctly, there is a database in your organization that needs to be accessed via REST API in a platform-independent way.
I assume you want to use Node.js, since there are some examples available in SO for your use case.
But there is also a JavaScript client library, with which the Google APIs are accessible:
Google API Client Library for JavaScript https://github.com/google/google-api-javascript-client
Using the JavaScript Client Library https://cloud.google.com/compute/docs/tutorials/javascript-guide
We use asynchronous calls to minimize the impact of latency. In this respect, your JavaScript endpoint must be able to communicate asynchronously.
This should be possible with BANano (please correct me, @alwaysbusy, if I'm wrong).:
Working with promises https://www.b4x.com/android/forum/threads/banano-working-with-promises.102413/
[BANano] [SOLVED] What is the right way to use BANano.WaitFor? https://www.b4x.com/android/forum/t...s-the-right-way-to-use-banano-waitfor.127285/
The hurdle for accessing Google API data can still be influenced by choosing the right authentication. In addition to the API key method, there is also the option of using an access token via service account.
If your use case allows it, Cloud Datastore can be upgraded to Firestore and run in Datastore mode (Firestore is the next generation of Datastore).
This opens up the possibility to take full advantage of Firebase authentications:
Automatic Upgrade to Firestore https://cloud.google.com/datastore/docs/upgrade-to-firestore
Firebase Authentication https://firebase.google.com/docs/auth
BTW here is a sample code for the "Google Compute Engine API", which could be usable for your case:
Google Compute Engine JavaScript Sample Application: https://github.com/GoogleCloudPlatform/compute-getting-started-javascript
#If JAVASCRIPT
function loadlib(){
console.log("loaded client libs");
gapi.load('client:auth2', initClient);
}
var apiKey = 'xxxxxxxxx40mIGihqJ98kyLpxxxxxxxxxxxx';
var clientId = '875655xxxxxxxxxxxx.apps.googleusercontent.com';
var discoveryDocs = ["https://datastore.googleapis.com/$discovery/rest?version=v1"];
var scopes = 'https://www.googleapis.com/auth/datastore';
function initClient() {
console.log("apiKey: " + apiKey);
console.log("clientId: " + clientId);
console.log("scopes: " + scopes);
gapi.client.init({
apiKey: apiKey,
discoveryDocs: discoveryDocs,
clientId: clientId,
scope: scopes
}).then(function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
console.log("isSignedIn: " + gapi.auth2.getAuthInstance().isSignedIn);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
//authorizeButton.onclick = handleAuthClick;
//signoutButton.onclick = handleSignoutClick;
});
}
function updateSigninStatus(isSignedIn) {
if (isSignedIn) {
//authorizeButton.style.display = 'none';
// signoutButton.style.display = 'block';
// makeApiCall();
console.log("isSignedIn: " + isSignedIn);
} else {
//authorizeButton.style.display = 'block';
// signoutButton.style.display = 'none';
console.log("notSignedIn: " + isSignedIn);
}
}
function SignIn(){
console.log("signing in");
gapi.auth2.getAuthInstance().signIn();
}
#End If
BANano.Header.AddJavascriptFile("https://apis.google.com/js/client.js")
BANano.Header.AddJavascriptFile("https://apis.google.com/js/api.js")
Sub BANano_Ready()
Dim body As BANanoElement = BANano.GetElement("#body")
body.Append("Hello Walter")
BANano.RunInlineJavascriptMethod("loadlib", Null)
BANano.Sleep(500)
BANano.RunInlineJavascriptMethod("SignIn", Null)
End Sub
function execute(Kind, ID) {
return gapi.client.datastore.projects.lookup({
"projectId": "snaplab-993",
"resource": {
"readOptions": {
"readConsistency": "EVENTUAL"
},
"keys": [
{
"path": [
{
"kind": Kind,
"id": ID
}
],
"partitionId": {
"namespaceId": "current_drain_data",
"projectId": "snaplab-993"
}
}
]
}
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
},
function(err) { console.error("Execute error", err); });
return response;
}
BANano.RunInlineJavascriptMethod("execute", Array ("waveform", 5633571828006912))
Response {
"found": [
{
"entity": {
"key": {
"partitionId": {
"projectId": "snaplab-993",
"namespaceId": "current_drain_data"
},
"path": [
{
"kind": "waveform",
"id": "5633571828006912"
}
]
},
"properties": {
"ch0": {
"arrayValue": {
"values": [
{
"doubleValue": 59.961688893613768,
"excludeFromIndexes": true
},
{
"doubleValue": 49.6029332019204,
"excludeFromIndexes": true
},
{
"doubleValue": 51.303013130144294,
"excludeFromIndexes": true
},
{
"doubleValue": 61.339663028985122,
"excludeFromIndexes": true
},
{
"doubleValue": 56.875304507789565,
"excludeFromIndexes": true
},
{
"doubleValue": 58.992594740979818,
"excludeFromIndexes": true
},
{
"doubleValue": 57.622256734318327,
"excludeFromIndexes": true
},
Dim gapi As BANanoObject
LoadLib
Sub LoadLib()
Log("loaded client libs")
gapi.Initialize("gapi")
gapi.RunMethod("load", Array("client:auth2", BANano.CallBack(Me, "InitClient", Null)))
End Sub
Sub InitClient() 'ignore
Dim Params As Map
Params.Initialize
Params.Put("apiKey", "AIzaSyCAjcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
Params.Put("discoveryDocs", Array("https://datastore.googleapis.com/$discovery/rest?version=v1"))
Params.Put("clientId", "28675018xxxxxxxxxxxxxxxxxxxxxxxxxxxxge.apps.googleusercontent.com")
Params.Put("scope", "https://www.googleapis.com/auth/datastore")
BANano.Await(gapi.GetField("client").RunMethod("init", Params))
Log(gapi.GetField("auth2").RunMethod("getAuthInstance", Null).GetField("isSignedIn").RunMethod("get", Null))
End Sub
Private Sub SKButton1_Click (event As BANanoEvent)
Dim Projects As BANanoObject = gapi.GetField("client").GetField("datastore").GetField("projects")
Dim Kind as String = "waveform"
Dim ID as long = 1234567890123
Dim Params As String = $"
{
"projectId": "snaplab-993",
"resource": {
"readOptions": {
"readConsistency": "EVENTUAL"
},
"keys": [
{
"path": [
{
"kind": "${Kind}",
"id": ${ID}
}
],
"partitionId": {
"namespaceId": "current_drain_data",
"projectId": "snaplab-993"
}
}
]
}
}
"$
' make an object from the string
Params = BANano.FromJson(Params)
Log(Params)
Dim JsonObject As BANanoObject
Dim JsonStr as String
Dim prom As BANanoPromise = Projects.RunMethod("lookup", Params)
prom.then(JsonObject)
Log(JsonObject)
Return JsonObject.Body ' resolve the body part of the response stream
prom.then(JsonStr)
Dim newObj as BANanoObject = BANano.FromJson(jsonStr) ' let(s make a javascript json object from it
Dim founds() As BANanoObject = newObj.GetField("found") ' <----
Log(founds)
Dim values As List = founds(0).GetField("entity").GetField("properties").GetField("ch0").GetField("arrayValue").GetField("values")
For i = 0 To values.Size - 1
Dim m As Map = values.Get(i)
Log(m.Get("doubleValue"))
Next
prom.end
End sub
I am getting the following error:#if javascript _params = { "projectId": "snaplab-993", "resource": { "readOptions": { "readConsistency": "EVENTUAL" }, "keys": [ { "path": [ { "kind": _kind, "id": _id } ], "partitionId": { "namespaceId": "current_drain_data", "projectId": "snaplab-993" } } ] } } #End If
app.js:13 Uncaught (in promise) ReferenceError: _kind is not defined
at banano_waveformanalyzer.loaddata (app.js:13)
at banano_waveformanalyzer.initclient (app.js:3)
Dim Params As String = $"
{
"projectId": "snaplab-993",
"resource": {
"readOptions": {
"readConsistency": "EVENTUAL"
},
"keys": [
{
"path": [
{
"kind": "${Kind}",
"id": ${ID}
}
],
"partitionId": {
"namespaceId": "current_drain_data",
"projectId": "snaplab-993"
}
}
]
}
}
"$
' make an object from the string
Params = BANano.FromJson(Params)
log(Params)
...
That worked, but i am now getting another error:Can you PM me your app.js file? But I'm just thinking that my shortcut won't work in release mode anyway as the variables will be renamed to short ones.
Try this one instead:
B4X:Dim Params As String = $" { "projectId": "snaplab-993", "resource": { "readOptions": { "readConsistency": "EVENTUAL" }, "keys": [ { "path": [ { "kind": "${Kind}", "id": ${ID} } ], "partitionId": { "namespaceId": "current_drain_data", "projectId": "snaplab-993" } } ] } } "$ ' make an object from the string Params = BANano.FromJson(Params) log(Params) ...
Alwaysbusy
cb=gapi.loaded_0:981 Uncaught (in promise) mB {message: "Ma`projectId", wK: true, stack: "gapi.client.Error: Ma`projectId↵ at new mB (htt…ent (http://localhost:8887/scripts/app.js:3:1349)"}
initclient @ app.js:3
async function (async)
initclient @ app.js:3
(anonymous) @ app.js:3
(anonymous) @ api.js:15
fa @ api.js:8
A @ api.js:15
r.<computed> @ api.js:15
x.<computed> @ api.js:15
(anonymous) @ cb=gapi.loaded_1:1
No it doesn't, i don't know where that is coming from tbh.Does Ma`projectId mean something in your language?
I also get this error, if I don't comment out this lineDoes Ma`projectId mean something in your language?
Dim JsonObject As BANanoObject
Dim prom As BANanoPromise = projects.RunMethod("lookup", Array(params))
prom.then(JsonObject) 'if I leave this line uncommented I get an error
Uncaught SyntaxError: missing ) after argument list
Sub LoadLib()
Log("loaded client libs")
gapi.Initialize("gapi")
gapi.RunMethod("load", Array("client:auth2", BANano.CallBack(Me, "InitClient", Null)))
End Sub
Sub isSignedIn As Boolean
Return gapi.GetField("auth2").RunMethod("getAuthInstance", Null).GetField("isSignedIn").RunMethod("get", Null)
End Sub
Sub InitClient()
Dim params As Map
params.Initialize
params.Put("apiKey", API_KEY)
params.Put("discoveryDocs", Array("https://datastore.googleapis.com/$discovery/rest?version=v1"))
params.Put("clientId", Client_ID)
params.Put("scope", "https://www.googleapis.com/auth/datastore")
BANano.Await(gapi.GetField("client").RunMethod("init", params))
'''SignIn
Log("is SignedIn: " & isSignedIn)
If isSignedIn Then
gapi.GetField("client").RunMethod("setApiKey", API_KEY)
Log("loaded url: " & gapi.GetField("client").RunMethod("load", "https://content.googleapis.com/discovery/v1/apis/datastore/v1beta3/rest"))
LoadData
Else
SignIn
End If
End Sub
Sub SignIn
BANano.Await(gapi.GetField("auth2").RunMethod("getAuthInstance", Null).RunMethod("signIn", Null))
End Sub
BANano.Header.AddJavascriptFile("https://apis.google.com/js/client.js")
BANano.Header.AddJavascriptFile("https://apis.google.com/js/api.js")
Sub LoadData()
Dim projects As BANanoObject = gapi.GetField("client").GetField("datastore").GetField("projects")
Dim params As BANanoObject = $"
{
"projectId": "${ProjectID}",
"resource": {
"readOptions": {
"readConsistency": "EVENTUAL"
},
"keys": [
{
"path": [
{
"kind": "${Kind}",
"id": ${WaveFormID}
}
],
"partitionId": {
"namespaceId": "current_drain_data",
"projectId": "${ProjectID}"
}
}
]
}
}
"$
params = BANano.FromJson(params)
Dim jsonStr As BANanoObject
Dim err As Object
Dim JsonObject As BANanoFetchResponse
Dim prom As BANanoPromise = projects.RunMethod("lookup", params)
prom.then(JsonObject)
Return JsonObject.Body
prom.Then(jsonStr)
Log(BANano.IsJson(jsonStr))
Log(BANano.IsString(jsonStr))
Dim newObj As BANanoObject = BANano.FromJson(jsonStr) ' let(s make a javascript json object from it
Dim founds() As BANanoObject = newObj.GetField("found") ' <----
Log(founds)
Dim current As List = founds(0).GetField("entity").GetField("properties").GetField("ch0").GetField("arrayValue").GetField("values")
Dim time As List = founds(0).GetField("entity").GetField("properties").GetField("time").GetField("arrayValue").GetField("values")
Dim currVals(current.Size) As Double
Dim timeVals(time.Size) As Double
For i = 0 To current.Size - 1
Dim m1 As Map = current.Get(i)
currVals(i) = m1.Get("doubleValue")
Next
Dim mm As Map = time.Get(0)
Log("mm(0): " & mm.Get("doubleValue"))
For j = 0 To time.Size - 1
Dim m2 As Map = time.Get(j)
timeVals(j) = m2.Get("doubleValue")
Next
Log("currVals size: " & currVals.Length)
Log("timeVals size: " & timeVals.Length)
Dim description As String = ""
Dim err2 As BANanoObject
description = founds(0).GetField("entity").GetField("properties").GetField("description").GetField("stringValue")
Log("description: " & description)
PlotlyChart1.InitializePlotly(description, timeVals, currVals) 'PlotlyChart1 is the variable created from the PlotlyChart customview class, the parameters passed are X axis values, y Axis values and description for Title.
prom.Else(err)
Log("error: " & err)
BANano.ReturnThen("")
prom.end
End Sub
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?