I’ve put JSON and Ajax calls in one tutorial, as in many cases they go together anyway.
JSON
The JSONParser and JSONGenerator in B4JS are almost identical as their B4X versions. The only method not supported (yet) is NextValue. To be honest, I haven’t needed it in any of my projects yet so if someone knows a good example of its usage, please let me know.
This example is based on Erels example, without the reading from file part as this is not supported in B4JS.
public Sub TestJson() ' String -> JSON Dim JSON As JSONParser JSON.Initialize($"{"menu": { "id": "file", "value": "File", "popup": { "menuitem": [ {"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"} ] } }}"$) ' exploring the JSON tree Dim Map1 As Map Map1 = JSON.NextObject Dim m As Map 'helper map for navigating Dim MenuItems As List m = Map1.Get("menu") m = m.Get("popup") MenuItems = m.Get("menuitem") For i = 0 To MenuItems.Size - 1 m = MenuItems.Get(i) Log(m.Get("value")) Next ' manipulating and generating a new JSON file Dim Data As List Data.Initialize Data.Add(1) Data.Add(2) Data.Add(3) Data.Add(Map1) 'add the previous map loaded Dim JSONGenerator As JSONGenerator JSONGenerator.Initialize2(Data) Log(JSONGenerator.ToPrettyString(2)) End Sub
The end result is this:
New Open Close [ 1, 2, 3, { "menu": { "id": "file", "value": "File", "popup": { "menuitem": [ { "value": "New", "onclick": "CreateNewDoc()" }, { "value": "Open", "onclick": "OpenDoc()" }, { "value": "Close", "onclick": "CloseDoc()" } ] } } } ]
AJAX Calls
In many cases, when you call a REST API you receive a JSON string. We can use what we’ve learned in the previous topic to retrieve the data we want.
Making an AJAX call (to your own B4J server or an external one) can be done like this. The example is getting a test json file from JSONPlaceholder, a Fake Online REST API for testing and protoyping (https://jsonplaceholder.typicode.com).
Note: because I’m running this test locally, I use ‘jsonp’ as the dataType otherwise Chrome will not allow a cross-domain call.
Page.B4JSCallAjax("myJob1", "https://jsonplaceholder.typicode.com/posts/1", "GET", "jsonp", "" , "B4JSCalculateDistance")
the first parameter is the ‘jobID’ (somewhat like you are used to with JobDone in B4X)
The last parameter is where you want to get the events back (an empty string returns to the ABM Page class, else to the B4JS class name specified)
In the ABM Page class we can do something similar, but the events are always returned to the server (ABM Page class)
Page.CallAjax("myJob1", "https://jsonplaceholder.typicode.com/posts/1", "GET", "jsonp", "")
There are couple events we can use:
Note: in this example I’m using the B4JS versions:
Page_AjaxResult and Page_B4JSAjaxResult
Sub Page_B4JSAjaxResult(uniqueId As String, result As String) As Boolean Log("Result from: " & uniqueId & " = " & result) Dim JSON As JSONParser JSON.Initialize(result) Dim Map1 As Map Map1 = JSON.NextObject Log("UsedID: " & Map1.Get("userId")) ' if True, it will not call the Page_ajaxResult declared in the Page class! Return True End Sub
Page_AjaxError and Page_B4JSAjaxError
Sub Page_B4JSAjaxError(uniqueId As String, error As String) Log("We got an error: " & error) End Sub
The result is what we would expect:
Result from: myJob1 = {"userId":1,"id":1,"title":"sunt aut facere repellat provident occaecati excepturi optio reprehenderit","body":"quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"} UsedID: 1
Notice our ‘myJob1’ identifier we used in the CallAjax method.
This concludes the basic B4X to B4JS tools. In the next tutorial(s) we’ll dive into how to use this together with ABMaterial.
Alwaysbusy
Thank you!