B4J Question [BANano] [SOLVED] getting this.

Mashiane

Expert
Licensed User
Longtime User
Hi there

Whilst BANano.Spread gives ones "..." for variable names, I'm wondering if there is another "this" directive. From the look of things, defining bananoobject and initializing it with "this", gives this access to the class/code module.

B4X:
// [119] Private Sub btn_Click (e As BANanoEvent)
_B.vantelement1_click=function(_e) {
var _this;
// [120]  Dim this As BANanoObject
_this=null;
// [121]  this.Initialize( {18} )
_this=this;
// [122]  RefreshPage(vapp)
_B.refreshpage(_B._vapp,_B);
// [124]  VanBadge1.Increment
_B._vanbadge1.increment();
// End Sub
};

This is what I get when I log "this" inside one of my callbacks, which is methods belonging to the CodeModule..

1648120151279.png


However, lets look at this javascript code beforeMount and methods section, which have a this.$data directive.

B4X:
var vm = new Vue({
  el: '#vm',
  template: `<div>{{ item.count }}<input type="button" value="Click" @click="updateCount"/></div>`,
  data: {
    item: {}
  },
  beforeMount () {
    this.$data.item.count = 0;
  },
  methods: {
    updateCount () {
      // JavaScript object is updated but
      // the component template is not rendered again
      this.$data.item.count++;
    }
  }
});

There are 2 sections in the code where there is a reference to this.$data.

I am assuming that "this" in this instance refers back to the vm variable. I hope what I'm trying to explain has not been lost in translation. I'd like to use something similar in BANano if possible where one could be able to use "this" internally to that function, perhaps a BANanoObject also.

Thanks in advance.
 
Solution
The scope of 'this' is very special in JavaScript, and even more so in Vue. See https://lusaxweb.github.io/vuesax-blog/tips/scope_this.html#arrow-functions, especially the part 'Create Var' as I have not been able to find a way to enter an arrow syntax in the B4J IDE without the IDE causing errors.

There is an internal BANano directive that may be useful in your case: start a SmartString with [BANRAW] and BANano will transpile it as pure JavaScript.
B4X:
Dim options As BANanoObject    
    options.Initialize($"[BANRAW]{
  el: '#vm',
  template: `<div>{{ item.count }}<input type="button" value="Click" @click="updateCount"/></div>`,
  data: {
    item: {}
  },
  beforeMount () {
    this.$data.item.count = 0;
  },
  methods: {...

Mashiane

Expert
Licensed User
Longtime User
This is the current translation of the code above to BANano.... Perhaps with the extra this, it could be easier.

Assuming this is in a class...

B4X:
Sub class_globals
    private data As BANanoObject
    private methods As Map
    private vm As BANanoObject
End Sub

Sub Serve
    Dim beforeMountCB As BANanoObject = BANano.CallBack(me, "beforeMount", null)
    Dim dataCB As BANanoObject = BANano.CallBack(me, "returndata", null)
    Dim options As Map = CreateMap()
    options.put("el", "#vm") 
    options.put("template", $"<div>{{ item.count }}<input type="button" value="Click" @click="updateCount"/></div>"$)
    options.put("data", dataCB) 
    options.put("beforeMount", beforeMountCB)
    options.put("methods", methods)
    vm.Initialize2("Vue", options)
    dim vdata As String = "$data"
    data = vm.getfield(vdat)
End Sub

Sub returndata As BANanoObject
    return data
End Sub

Sub SetData(prop As String, value As Object)
      data.setfield(prop, value)
End Sub

Sub GetData(prop As String) As Object
    dim res as Object = data.getfield(prop)
    return res
End Sub

Sub AddMethod(methodName As String)
     dim args As List
     args.Initialize
     dim cb As BANanoObject = BANano.CallBack(me, methodName, BANano.Spread(args))
     methods.put(methodname, cb)
End Sub

Usage...

[code]
Sub Init
AddMethod("updateCount")
Serve
End Sub

Sub updateCount 
   dim item As Map = GetData("item")
   dim count As int = item.get("count")
   count = BANano.parseInt(count) + 1
   item.put("count", count)
   SetData("item", item)
End Sub

Sub beforeMount
      dim item As Map = CreateMap()
      item.put("count", 0)
      SetData("item", item)
End Sub
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
The scope of 'this' is very special in JavaScript, and even more so in Vue. See https://lusaxweb.github.io/vuesax-blog/tips/scope_this.html#arrow-functions, especially the part 'Create Var' as I have not been able to find a way to enter an arrow syntax in the B4J IDE without the IDE causing errors.

There is an internal BANano directive that may be useful in your case: start a SmartString with [BANRAW] and BANano will transpile it as pure JavaScript.
B4X:
Dim options As BANanoObject    
    options.Initialize($"[BANRAW]{
  el: '#vm',
  template: `<div>{{ item.count }}<input type="button" value="Click" @click="updateCount"/></div>`,
  data: {
    item: {}
  },
  beforeMount () {
    this.$data.item.count = 0;
  },
  methods: {
    updateCount () {
      this.$data.item.count++;
    }
  }
}"$)
    Dim vm As BANanoObject
    vm.Initialize2("Vue", options)

Result of options after transpiling:
B4X:
_options={el: '#vm',template: `<div>{{ item.count }}<input type=\"button\" value=\"Click\" @click=\"updateCount\"/></div>`,data: {item: {}},beforeMount () {this.$data.item.count = 0;},methods: {updateCount () {this.$data.item.count++;}}};

Alwaysbusy
 
Upvote 1
Solution

Mashiane

Expert
Licensed User
Longtime User
Update:

Whilst this is not about getting "this", this helped a lot to achieve what I needed to do in Vue3. My, a lot changed between Vue2 and Vue3.

 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
this.Initialize($"[BANRAW]this"$)
In this case you do not need [BANRaw] (only in a very specific case as described by Mashiane it is needed)

For your case, works the same:
B4X:
Dim this As BANanoObject
this.Initialize("this")
BANano.Console.Log(this)

Alwaysbusy
 
Last edited:
Upvote 0
Top