B4J Tutorial [BANano] Exploring BANanoObject.GetFunction & Execute

Ola

The newest version of BANano comes with a lot of enhancements and some very interesting stuff. There's so much to learn.

So I decided to check one interesting thing out, Getting / Executing a function.

What does this really mean, I thought.

Let's make a simple assumption based on a javascript Object.

B4X:
var cody = new Object(); 
cody.living = true; 
cody.age = 33; 
cody.gender = 'male'; 
cody.getGender = function () { return cody.gender; }; 
console.log(cody.getGender()); // Logs 'male'.

To try and demonstrate this, we will NOT use a map but an actual object and initialize it. For this I have created a JSObject class in my code. This JSObject class tries and replicates the simple example to create the above object.

1. var cody = new Object();

B4X:
obj.Initialize2("Object", Null)

2. cody.living = true; We will use the .setField for this

B4X:
obj.SetField(k, v)

and later..

3. cody.getGender = function () { return cody.gender; };

We need to create a callback function for this. We will do this in our module and use a global variable.

We have created a shortcut for this in our JSObject class.

B4X:
obj.setCallBack("getGender", Me, "getGender", Null)

Lets define a method to assign a callback to an object property.

B4X:
Sub getGender As String
    Return obj.get("gender")
End Sub

The property is getGender and the function to call should return the "gender" property of the object.

This .setCallBack method has been defined as..

B4X:
'set a callback
Sub setCallBack(k As String, module As Object, methodname As String, params As List)
    Dim cb As BANanoObject = BANano.CallBack(module, methodname, params)
    obj.SetField(k, cb)
End Sub

We pass it the module, method name and the params it needs.

To be able to run out "getGender" property, we need a way to have the function/callback execute from the object itself. For that we have created a method in our JSObject class to call.

B4X:
Log(obj.getCallBack("getGender"))

As our method is not passed any variables, we just define and call it with null. What getCallBack does is to read the property we previsouly defined. i.e. getGender => callback and then executes it.

B4X:
'get callback
Sub getCallBack(k As String) As BANanoObject
    Dim cb As BANanoObject = obj.GetFunction(k)
    Return cb.Execute(Null)
End Sub

We can extend this to have it accept params and pass them to .Execute. Because the "getGender" method returns something, thats why I have returned cb.Execute.

I'm also getting my head around this, however I hope it provides some green lights into the methodology.

#You are welcome to add/improve/correct anything on the thread.

#TheUsualExperimentor

PS: The complete code

B4X:
'Static code module
Sub Process_Globals
    Private BANano As BANano  'ignore
    Private obj As JSObject
End Sub


Sub Init
    obj.Initialize
    obj.set("living", True)
    obj.set("age", 33)
    obj.set("gender", "male")
    obj.setCallBack("getGender", Me, "getGender", Null)
    
    Log(obj.It)
    Log(obj.ToJSON)
    Log(obj.getCallBack("getGender"))
End Sub


Sub getGender As String
    Return obj.get("gender")
End Sub

Results of the logs

getexecute.png
 

Attachments

  • JSObject.zip
    2.3 KB · Views: 294

alwaysbusy

Expert
Licensed User
Longtime User
This is a good example of the use of GetFunction and Execute, however i would've solved it differently so it is easier to 'use' the object and a bit more B4J like IMO. GetFunction is not really needed here (execute runs on a BANanoObject), but it can make your code a bit more readable so that is fine.

A class Human:
B4X:
Sub Class_Globals
   Private BANano As BANano 'ignore
   Public Living As Boolean
   Public Age As Int
   Public Gender As String
   Public GenderCallback As BANanoObject
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
  
End Sub

Public Sub GetGender() As String
   Return GenderCallback.Execute(Array(Me)).Result
End Sub

public Sub ToJson() As Object
   Return BANano.ToJson(CreateMap("living": Living, "age" : Age, "gender" : Gender))
End Sub

Usage (very similar to the javascript sample) and an example of 'why' one would use such a system:
B4X:
Sub init
   Dim cody As Human
   cody.Initialize
   cody.Living = True ' <--- normal properties
   cody.Age = 33
   cody.Gender = "male"
   cody.GenderCallback = BANano.CallBack(Me, "getGender", Array(cody))  
   Log(cody.ToJson)
   Log(cody.GetGender)
  
   ' lets change the callback and re-run the same GetGender method
   cody.GenderCallback = BANano.CallBack(Me, "getGenderUpperCase", Array(cody))  
   Log(cody.GetGender)
End Sub

' a first callback
Sub getGender(who As Human) As String 'ignore
   Return who.Gender
End Sub

' a second callback
Sub getGenderUpperCase(who As Human) As String 'ignore
   Return who.Gender.ToUpperCase
End Sub

So adding such a CallBack property allows you to Execute different functions, while still making the same call.

Result:
B4X:
{"living":true,"age":33,"gender":"male"}
male
MALE

Alwaysbusy
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
;)

Looks nice...

I need to wrap my head around this.

B4X:
Public Sub GetGender() As String
   Return GenderCallback.Execute(Array(Me)).Result
End Sub

Secondly, in most of javascript libs, one initializes them with an object {} that will have properties and property functions as per example.

So instead of

B4X:
var xxx = new Lib({'name':'BANano', 'getGender': function(){...}})

can one use?

B4X:
dim className as clsClass
className.Initialize
className.name = "BANano4"
className.TheCallBack = ...

Dim xxx as bananoobject
xx.Initialize2("Lib", array(className))

Where the className will point to the class we have created with those properties and property functions? So instead of passing an object we pass the class we have defined with properties and its own callback functions?

#Just Thinking Aloud
 
Last edited:
Top