Does anyone have an example of parsing a multidimensional JSON array?

Hi all,

I am looking for a bit of help/guidance.

I have managed to write a basic widget that calls a PHP service I have written to return a JSON feed containing the information I want to show on the watch, 

I now want to extend the JSON response to a multidimensional array, again created by my custom PHP (which I hope simplifies the code required in monkeyC). 

the extended JSON feed initially shows the pertinent information for today and subsequent days' information. 

I want to enable selecting the day's information via the menu or allow users to scroll through the array using the up and down buttons. (I'm a 6xpro owner)

But right now I don't know how to receive the JSON array let alone how to reference in a menu. 

I'm not a developer but can (usually) figure things out when having a working example to guide me.

Appreciate any help on this!.

Current BASIC JSON feed

 {"location":"location ","status":"falling","lc":"4hr 39min","lt":"16:56 GMT","hc":"9hr 19min","ht":"21:36 GMT","time":1647865029}

Current monkeyC

function LETideData(responseCode as Number, data as Dictionary?) {
	var result;
	$.p(responseCode);
	if (responseCode == 200) {	
		result = [responseCode,
			data["location"],	// 1 - name ("")
			data["status"],		// 2 - Condition ("")
			data["hc"],        	// 3 - countdown to high tide ("")
			data["ht"],			// 4 - High tide time ("")
			data["lc"],			// 5 - Low tide countdown ("")
			data["lt"],			// 6 - low tide time ("")
			data["time"]        // timestamp to show elapsed time from last update
			];
	// HTTP error
	} else {
		result = [responseCode];
	}

The new array is:

{
    "location": "location",
    "Dist": "5.1 km",
    "Index": 6,
    "Status": "Falling",
    "height": "1mtrs",
    "nc": "5hrs 37mins",
    "nt": "16:56",
    "fc": "10hrs 17mins",
    "ft": "21:36",
    "time": 1647861510,
    "0": {
        "timestamp": "2022-03-20 04:17:00",
        "index": 0,
        "type": "Low",
        "height": "0.9mtrs",
        "diff": "1day 7hrs"
    },
    "1": {
        "timestamp": "2022-03-20 08:42:00",
        "index": 1,
        "type": "High",
        "height": "11.9mtrs",
        "diff": "1day 2hrs"
    },
    "2": {
        "timestamp": "2022-03-20 16:34:00",
        "index": 2,
        "type": "Low",
        "height": "1mtrs",
        "diff": "18hrs 44mins"
    },
    "3": {
        "timestamp": "2022-03-20 21:03:00",
        "index": 3,
        "type": "High",
        "height": "11.8mtrs",
        "diff": "14hrs 15mins"
    },
    "4": {
        "timestamp": "2022-03-21 04:43:00",
        "index": 4,
        "type": "Low",
        "height": "0.9mtrs",
        "diff": "6hrs 35mins"
    },
    "5": {
        "timestamp": "2022-03-21 09:17:00",
        "index": 5,
        "type": "High",
        "height": "11.9mtrs",
        "diff": "2hrs 1min"
    },
    "6": {
        "timestamp": "2022-03-21 16:56:00",
        "index": 6,
        "type": "Low",
        "height": "1mtrs",
        "diff": "5hrs 37mins"
    },
    "7": {
        "timestamp": "2022-03-21 21:36:00",
        "index": 7,
        "type": "High",
        "height": "11.7mtrs",
        "diff": "10hrs 17mins"
    },
    "8": {
        "timestamp": "2022-03-22 05:04:00",
        "index": 8,
        "type": "Low",
        "height": "1mtrs",
        "diff": "17hrs 45mins"
    },
    "9": {
        "timestamp": "2022-03-22 09:52:00",
        "index": 9,
        "type": "High",
        "height": "11.7mtrs",
        "diff": "22hrs 33mins"
    },
    "10": {
        "timestamp": "2022-03-22 17:13:00",
        "index": 10,
        "type": "Low",
        "height": "1.1mtrs",
        "diff": "1day 5hrs"
    },
    "11": {
        "timestamp": "2022-03-22 22:11:00",
        "index": 11,
        "type": "High",
        "height": "11.3mtrs",
        "diff": "1day 10hrs"
    },
    "12": {
        "timestamp": "2022-03-23 05:27:00",
        "index": 12,
        "type": "Low",
        "height": "1.1mtrs",
        "diff": "1day 18hrs"
    },
    "13": {
        "timestamp": "2022-03-23 10:29:00",
        "index": 13,
        "type": "High",
        "height": "11.2mtrs",
        "diff": "1day 23hrs"
    },
    "14": {
        "timestamp": "2022-03-23 17:36:00",
        "index": 14,
        "type": "Low",
        "height": "1.2mtrs",
        "diff": "2days 6hrs"
    },
    "15": {
        "timestamp": "2022-03-23 22:48:00",
        "index": 15,
        "type": "High",
        "height": "10.7mtrs",
        "diff": "2days 11hrs"
    },
    "16": {
        "timestamp": "2022-03-24 05:54:00",
        "index": 16,
        "type": "Low",
        "height": "1.2mtrs",
        "diff": "2days 18hrs"
    },
    "17": {
        "timestamp": "2022-03-24 11:10:00",
        "index": 17,
        "type": "High",
        "height": "10.3mtrs",
        "diff": "2days 23hrs"
    },
    "18": {
        "timestamp": "2022-03-24 18:06:00",
        "index": 18,
        "type": "Low",
        "height": "1.4mtrs",
        "diff": "3days 6hrs"
    },
    "19": {
        "timestamp": "2022-03-24 23:31:00",
        "index": 19,
        "type": "High",
        "height": "9.7mtrs",
        "diff": "3days 12hrs"
    },
    "20": {
        "timestamp": "2022-03-25 06:28:00",
        "index": 20,
        "type": "Low",
        "height": "1.6mtrs",
        "diff": "3days 19hrs"
    },
    "21": {
        "timestamp": "2022-03-25 12:00:00",
        "index": 21,
        "type": "High",
        "height": "9.2mtrs",
        "diff": "4days 41mins"
    },
    "22": {
        "timestamp": "2022-03-25 18:44:00",
        "index": 22,
        "type": "Low",
        "height": "1.8mtrs",
        "diff": "4days 7hrs"
    },
    "23": {
        "timestamp": "2022-03-26 00:28:00",
        "index": 23,
        "type": "High",
        "height": "8.7mtrs",
        "diff": "4days 13hrs"
    },
    "24": {
        "timestamp": "2022-03-26 07:18:00",
        "index": 24,
        "type": "Low",
        "height": "2mtrs",
        "diff": "4days 19hrs"
    },
    "25": {
        "timestamp": "2022-03-26 13:15:00",
        "index": 25,
        "type": "High",
        "height": "8.2mtrs",
        "diff": "5days 1hr"
    },
    "26": {
        "timestamp": "2022-03-26 19:44:00",
        "index": 26,
        "type": "Low",
        "height": "2.2mtrs",
        "diff": "5days 8hrs"
    },
    "27": {
        "timestamp": "2022-03-27 02:11:00",
        "index": 27,
        "type": "High",
        "height": "8mtrs",
        "diff": "5days 14hrs"
    },
    "28": {
        "timestamp": "2022-03-27 09:25:00",
        "index": 28,
        "type": "Low",
        "height": "2.2mtrs",
        "diff": "5days 22hrs"
    },
    "29": {
        "timestamp": "2022-03-27 15:14:00",
        "index": 29,
        "type": "High",
        "height": "8.1mtrs",
        "diff": "6days 3hrs"
    },
    "30": {
        "timestamp": "2022-03-27 22:37:00",
        "index": 30,
        "type": "Low",
        "height": "2.2mtrs",
        "diff": "6days 11hrs"
    }
}

  • 1. array in json should be coded like this

    ..

     "time": 1647861510,
    "marray": [
    {
            "timestamp": "2022-03-20 04:17:00",
            "index": 0,
            "type": "Low",
            "height": "0.9mtrs",
            "diff": "1day 7hrs"
    },
    {
            "timestamp": "2022-03-20 16:34:00",
            "index": 2,
            "type": "Low",
            "height": "1mtrs",
            "diff": "18hrs 44mins"
        },
    ...
    ]
    ...

    2. in Monkey C data["marray"] returns multi dimensional array

  • Thanks, I can change the array, thought it might be better the other way in order to show today's closest result and then allow scrolling onwards or backwards through the array/date. 

    If this is the way to do it, would the result be referenced as data[marray][2] ?

  • rather data["marray"][2] and is index of array

    but of course check json syntax because I haven't test it - it's "general view"

  • I'm still struggling with this if anyone finds a good example or link to a github project, please let me know. 

  • example of json or code?

  • my app uses this, and it’s based off the Yet another  sailing app code which is on GitHub the code loads a set of navigation routes and you can scroll through the routes to select one, it’s pretty straight forward, I’m travelling at the moment but can post my version here if it’s still not working for you

    github.com/.../Yet-Another-Sailing-App

  • Thanks Robin, that's a big help

  • HI Robin, I wonder if you might be able to share your code, I'm close but another example would likely get me across the line. Thanks

  • This part is to load the JSON to a variable (you can download the JSON File to Review by following the link,

    hidden function makeLoadRoutesRequest()
    	{
     var options = {
              :method => Comm.HTTP_REQUEST_METHOD_GET,
              :responseType => Comm.HTTP_RESPONSE_CONTENT_TYPE_JSON
            };
    url= "https://onedrive.live.com/download?cid=CC6EDA0EE1288F72&resid=cc6eda0ee1288f72%21187432&authkey=AIGQUy2tii1ka-U";
    
    Comm.makeWebRequest(url, {}, options, method(:onReceive));
    	 }
    
    
    function onReceive(responseCode, data)
    	{
    		if (responseCode != 200)
    		{
    			_loadingError = responseCode;
    			
    		}
    		else
    		{
    			_routesData = data["routes"];
    		}
    
    		Ui.requestUpdate();
    	}

    This is to swap between the Routes availiable

    function NextRoute()
    	{
    		if (_routesData == null)
    		{
    			return;
    		}
    		
    		if ( _selectedRouteId < _routesData.size() - 1)
    		{
    			_selectedRouteId++;
    		}
    		Ui.requestUpdate();
    	}
    	
    	function PreviousRoute()
    	{
    		if (_routesData == null)
    		{
    			return;
    		}
    			
    		if (_selectedRouteId > 0)
    		{
    			_selectedRouteId--;
    		}
    		Ui.requestUpdate();
    	}
    	
    	function RouteSelected()
    	{
    		if (_routesData == null)
    		{
    			return;
    		}
    		Settings.CurrentRoute = _routesData[_selectedRouteId];
    		Ui.popView(Ui.SLIDE_IMMEDIATE);
    	}

    This is printing some of the data on the screen for the user to review the selcted course prior to navigating,

    function PrintSelectedRoute(dc, selectedRouteData, selectedRouteId, routesSize)
    	{
    		var mid = dc.getWidth()/2;
    
    		//Sys.println(selectedRouteData);
    
    		dc.setColor(Settings.ForegroundColor, Settings.BackgroundColor);
    		dc.clear();
    		
    	    dc.setColor( Settings.ForegroundColor, Settings.BackgroundColor);
        	dc.drawText(mid, dc.getHeight()*30/280, Gfx.FONT_SYSTEM_SMALL, Lang.format("Select Route\n$1$  [ $2$ ]", [selectedRouteId + 1, routesSize]), Gfx.TEXT_JUSTIFY_CENTER);
        	dc.setColor( Settings.ForegroundColor, Settings.BackgroundColor);
      		
        	dc.drawText(mid, dc.getHeight()*140/280, Gfx.FONT_SYSTEM_XTINY, selectedRouteData["RouteName"], Gfx.TEXT_JUSTIFY_CENTER);	
        	dc.drawText(mid, dc.getHeight()*170/280, Gfx.FONT_SYSTEM_XTINY, "WayPoints : " + selectedRouteData["WayPoints"].size(), Gfx.TEXT_JUSTIFY_CENTER);	
    		dc.drawText(mid, dc.getHeight()*200/280, Gfx.FONT_SYSTEM_XTINY, Common.DateJson2Short(selectedRouteData["RouteDate"]), Gfx.TEXT_JUSTIFY_CENTER);
        	
        	if (selectedRouteId > 0)
        	{
        		dc.fillPolygon([[mid, dc.getHeight()*120/280], [mid - 10, dc.getHeight()*130/280], [mid + 10, dc.getHeight()*130/280]]);
        	}
        	
        	if (selectedRouteId < routesSize - 1)
        	{
        		dc.fillPolygon([[mid, dc.getHeight()*250/280], [mid - 10, dc.getHeight()*240/280], [mid + 10, dc.getHeight()*240/280]]);
        	}	    	 
    	}

    This final bit is how you can create an array on the fly similar to the data you would get in the JSON Import, where Windward is static var Windward = [0,0]; updated to a pair of co-ordinates (the same waypoint is added 6 times to count laps)

      var waypoint = {
                "Lat" => windward[0],
                "Lon" => windward[1],
                "Name" => "Windward Mark 00"
            };
            var waypoints = {
                0 => waypoint,
                1 => waypoint,
                2 => waypoint,
                3 => waypoint,
                4 => waypoint,
                5 => waypoint
            };
    
    
            var route = {
                "RouteName" => "Windward Mark",
                "RouteDate" => windward[2],
                "WayPoints" => waypoints
             
            };

    let me know if you have any questions on any of the above 

  • Thanks robin, I presume the element "to swap between the Routes available" is called from a menu class?