Lesson 9 - Tips and Tricks
This section shall expose some items that are useful when developing, testing and deploying our apps.
Log Each Button Click Event
On each page, in the sub Page_ParseEvent(Params As Map) add a log item to show what the events are - and the params required.
This helps you discover "why" your assumed event section is not being raised (for example)...
Code:
Sub Page_ParseEvent(Params As Map)
Dim eventName As String = Params.Get("eventname")
Dim eventParams() As String = Regex.Split(",",Params.Get("eventparams"))
' log each event click...
Log(" Event name: "&eventName&" "&Params)
Save a Log File To Disk
Trying to discover why your app on the remote server "sometimes" has issues can be so much fun...
Write a file with all log outputs you can look at later - when issues are reported.
In the the AppStart section of Main, add - ABMShared.RedirectOutput(File.DirApp,"mylogs.txt") - as the last line...
Code:
Sub RedirectOutput (Dir As String, FileName As String) 'ignore
#if RELEASE
Dim out As OutputStream = File.OpenOutput(Dir, FileName, False) 'Set to True to append the logs
Dim ps As JavaObject
ps.InitializeNewInstance("java.io.PrintStream", Array(out, True, "utf8"))
Dim jo As JavaObject
jo.InitializeStatic("java.lang.System")
jo.RunMethod("setOut", Array(ps))
jo.RunMethod("setErr", Array(ps))
#end if
End Sub
Watch For Incoming Files
My server app collects much data from mobile clients. This data consists of one or more files contained in a zipped file.
When the zips arrive (in a defined folder), they need to be un-zipped, in a select folder, so users can view the contents...
Check jFileWatcher in the libs tab...
In Main:
Sub Process_Globals
Public fw As FileWatcher
Public ecmFolder As String = File.DirApp &"/www/myapp/ecmfiles"
Sub AppStart (Args() As String)
fw.Initialize("fw").SetWatchList(Array As String(ecmFolder)).StartWatching ' watch this folder for new files...
When FileWatcher event is raised (new incoming file):
Code:
Sub fw_CreationDetected(FileName As String)
Log("CreationDetected: " & FileName) 'Logs the creation of a new file or folder
If inprocess = False Then
inprocess = True
proctimer.Enabled = True
End If
End Sub
I start a Timer to process the batch...
Code:
' timer sub...
Sub prtim_tick
Dim lof As List
lof.Initialize
lof = File.ListFiles(ecmFolder) ' create a list of filenames in this folder to process
For i = 0 To lof.Size -1
Dim str As String
str = lof.Get(i)
If str.Contains(".zip") Then
csu.CallSubDelayedPlus2(Me, "ProcessEcmZips", 2000, Array(str))
End If
Next
proctimer.Enabled = False ' stop the timer and reset the flag
inprocess = False
End Sub
' process sub...
Sub ProcessEcmZips(fn() As Object)
Log(" will process this file: "&fn(0))
' Now process the zip file...
' delete the incoming file so it won't get re-processed...
End Sub
Use Page.MsgBox2 For Modal Dialogs
Way back when, we were forced to create our own modal dialogs using sheets. No longer the case - (sweet)...
Position them anywhere and style them to your hearts content!
Example:
page.Msgbox2("DOWNL","Download the Android Mobile App","Get Device Application","Download","Cancel",False,ABM.MSGBOX_TYPE_QUESTION,False,ABM.MSGBOX_POS_CENTER_CENTER,"")
Result Dialog:
The dialog result sub... This is where we take action based on "which" dialog was shown and "what" button was clicked...
This keeps all your click actions in one nice tight sub...
Code:
Sub page_MsgboxResult(returnName As String, result As String)
If result = ABM.MSGBOX_RESULT_OK Then ' log only when OK was clicked...
Log(" OK was pressed Return name: "&returnName&" result: "&result)
End If
Select Case returnName
Case "DOWNL"
' ... Start of "DOWNL"
Log(" what is result: "&result)
Select Case result
Case "abmok"
Dim add As String = "../../apks/tinspect.apk"
ws.Eval("window.location = arguments[0]", Array As Object(add))
ws.Flush
Log(" DOWNL - tried to download the apk")
End Select
' ... End of "DOWNL"
Case "NEXT1" ' some other Msgbox2 on the same page...
' ...
Case "NEXT2" ' some other Msgbox2 on the same page...
' ...
Case "NEXT3" ' some other Msgbox2 on the same page...
' ...
End Select
End Sub
Using page.ShowToastWithReturns
This example ( from member
David Elkington ) explains how to use Toast Messages effectively...
Code:
'Call the toast...
If bolToastShowing = False Then ' I use this to stop the reoccurrence
page.ShowToastWithReturns("tConfirmEmail","ToastPurpleC","Send email:",5000, Array As String("Click to Confirm"),Array As String("Yes"),False)
bolToastShowing = True
End If
Sub Page_ToastClicked(toastID As String, Action As String)
If toastID="tConfirmEmail" Then
If Action="Yes" Then
' Do your email action
page.showToast("tDone","ToastGreen","Email has been queued",2000,False)
bolToastShowing=False
End If
End If
End Sub
Sub Page_ToastDismissed(ToastId As String) ' toast dismissed...
If ToastId="tconfirmemail" Then
bolToastShowing=False
End If
End Sub
Use Unique ID's When Creating Elements / Objects
This is very important to ensure formatting / themes are assigned properly.
For example when creating ABMTable rows:
Code:
public Sub ConnectPage()
' connecting the navigation bar
ABMShared.ConnectNavigationBar(page)
Dim tb As ABMTable
tb.Initialize(page, "tbl", False, False, True, "ttt")
tb.SetHeaders(Array As String("Head1", "Head2", "Head3"))
Dim alt As Boolean = True
For i = 0 To 10
Dim row As List
Dim rowT As List
row.Initialize
rowT.Initialize
For j = 0 To 2
Dim st As String = Rnd(0,1000)
row.Add(st)
If alt Then rowT.Add("cc1") Else rowT.Add("cc2")
Next
'******************************************************
' tb.AddRow("", row) ' this is wrong - no unique ID
tb.AddRow("uid" & i, row) ' this is correct - has unique ID for each row in table
'******************************************************
tb.SetRowThemes(rowT)
alt = Not(alt)
Next
page.Cell(1, 1).AddComponent(tb)
' refresh the page
page.Refresh
' Tell the browser we finished loading
page.FinishedLoading
' restoring the navigation bar position
page.RestoreNavigationBarPosition
End Sub
Run Your App in Debug Mode to Generate the CopyMeWithJar.needs File
In debug mode, your code is analyzed for newly added components and this file is updated to include these components. Run in debug just before release of your app to ensure this file gets updated.
Got any tips / tricks or useful snippets for us ABMers?
PM me and I will add them to this section!