B4J Question [BANano]: [SOLVED] Uncaught RangeError: Maximum call stack size exceeded

Mashiane

Expert
Licensed User
Longtime User
Hi there

I have a universal sub inside a class that I want to use to generate icons as defined below. I am using 'Me' in the class to self reference it.

B4X:
Sub getMaterialIcon(sID As String, sIconName As String, iconPos As String, sIconTheme As String, sIconCircle As Boolean, bWave As Boolean, bCursor As Boolean, bPrefix As Boolean, bClose As Boolean) As String
    'check if floating buttons and make icon a circle
    If sIconName.Length > 0 Then
        Dim icn As BANanoMaterialIcon
        icn.Initialize(Me, sID & "icon",sIconName,sIconTheme)
        icn.IconName = sIconName
        icn.Alignment = iconPos
        icn.AddCursor = bCursor
        icn.Circle = sIconCircle
        icn.WavesEffect = bWave
        icn.Prefix = bPrefix
        icn.Theme = sIconTheme
        icn.Close = bClose
        Return icn.ToString
    Else
        Return ""
    End If
End Sub

For BANanoMaterialIcon, Initialize(Me... expects a global variable, I have called it App.

If I put this code at module level and replace Me with App, everything works. Im sure Im missing something somewhere.
 

Mashiane

Expert
Licensed User
Longtime User
PS: I have changed the thread title as its the correct error

I've managed to reproduce this with two projects, one being a lib with 2 or so classes and the other a test project.

Things to note:

1. In the library BANanoJQM, there is a class called JQMPage, this is just a container that can hold other components.
2. This class comes containing other components, these are JQMContainers for heading, body, footer, I am using the "Me" keyword to initialize these..

JQMPage code...
B4X:
Sub Class_Globals
    Public BANano As BANano
    Public ID As String
    Public Header As JQMContainer
    Public Content As JQMContainer
    Public Footer As JQMContainer
    Private Page As JQMContainer

Initialize JQMPage object..

B4X:
'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(thisApp As JQMApp, sID As String)
    App = thisApp
    Events.Initialize
    Events.clear
    ID = sID.ToLowerCase
    'define the page
    Page.Initialize(Me,ID)
    Page.element.setdatarole("page")
    'define the header
    Header.Initialize(Me,$"${ID}hdr"$)
    Header.SetAttrData("role", "header")
    'define the page content
    Content.Initialize(Me,$"${ID}cnt"$)
    Content.SetattrData("role", "main")
    Content.addClass("ui-content")
    'define the footer
    Footer.Initialize(Me,$"${ID}ftr"$)
    Footer.setAttrData("role", "footer")
   
    Cache = False
    DataURL = ""
    FullScreen = False
    Theme = ""
End Sub

As noted above, I am initializing the Header, Content, Footer and Page using .Initialize(Me... self referencing the same class object. The library compilation works as expected, thing is when using the lib in a test project, there is a RangeError

B4X:
Uncaught RangeError: Maximum call stack size exceeded

When I remove the class reference and change the Initialize subroutines in the library and test project and reference the JQMApp class instead, everything works well. Im sure its my design style and this is not a BANano issue but a javascript error, but anyway I have included the Demo project also should you wish to take a look. So long I'm not self referencing classes.
 

Attachments

  • BANanoLibTest.zip
    460.9 KB · Views: 306
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
BANano will always make a 'new' class if dimmed. (classes and modules have no meaning in javascript like they do in B4J).

You can try to prevent this by explicitly giving it a value at dim point e.g. :

B4X:
Public Page As JQMPage = Null

The code doesn't run yet but that is because in your ToStyle method you are doing some wrong replaces with undefined and null (threating them as strings, while in Javascript null and undefined are actual values, not strings)
 
Upvote 0

Mashiane

Expert
Licensed User
Longtime User
After much thought, remembered Firefox developer, its nicely calling the error : Too much recursion, i will try and minimize the number of chaining subs and see what happens.

Update:

The chaining is not the issue, wish I knew that before I removed such on the subs, the generated banano code provided an answer, thanks for pointing me to using debug for that. The problem is my design, I created self referencing classes and these create the endless loop that lead to the crash. I just need to work around how I write the code to work. As an example

JQMPage is a class and it has a component instance if JQMContainer, the JQMContainer refences the JQMPage instance... (see last lines of these code blocks)

B4X:
function banano_selfreferencing_jqmpage() {
    var self;
    this._id = '';

    this._content = new banano_selfreferencing_jqmcontainer();

B4X:
function banano_selfreferencing_jqmcontainer() {
    var self;
    this._id = '';

    this._page = new banano_selfreferencing_jqmpage();

I created a simple project without resources to test the theory.

My thoughts:

To Initialize JQMContainer one needs to reference JQMPage as there are some methods universal in JQMPAge that are needed. What happens above is, each new instance of JQMPage created, it creates an instance Content of JQMContainer, when the Content JQMContainer is created, because it references the JQMPage, it also creates an instance Page JQMPage.

Loop Trail

1. JQMPage--> Content (JQMContainer)
2. Content (JQMContainer) --> Page (JQMPage) - goes back to 1
3. Crash

Ta!
 

Attachments

  • SelfReferencing.zip
    2.3 KB · Views: 274
Last edited:
Upvote 0
Top