how do you do callbacks?

Hey all.  I'm new to Monkey C, though am a JavaScript developer by trade. 

I'm trying to build a widget for my watch, but getting a bit stuck in callback ***.  Wondering if there's anyone that can offer guidance, or if there are any discord/irc servers for Monkey C development that I can hang in.

My main issue at the moment is that on getInitialView() I am doing a web request that will eventually set off other web requests, but i'm struggling to get the data that is returned from the web request back into getInitialView().

So my Widget code looks a little like this:

function getInitialView() as [Views] or [Views, InputDelegates] {
  System.println("hello! Lat and Long!");
  var pos = Position.getInfo().position.toDegrees();
  var places = place.getPlaceByLocation(pos[0], pos[1], 100.0);
  System.println(places);
}

When I output places, I get null.  Within my place class, it looks like this:
using Toybox.Lang;

class Place extends API {
    hidden var placeURL;
    hidden var data;
    var places;

    function initialize() {
        API.initialize();
        placeURL = "/Place/";
    }

    function getPlaceByLocation(lat as Lang.Float, lon as Lang.Float, radius as Lang.Double) {
        var url = self.placeURL + "?Lat=" + lat + "&Lon=" + lon + "&radius=" + radius.format("%.2f");

        return makeRequest(url, method(:setPlacesByLocation));
    }

    function setPlacesByLocation() {
        System.println("got here");
        places = new Places(API.getData());
        return places;
    }
}

Now, from the debugging, I know that my setPlacesByLocation() function is being called after the makeRequest is called and is correctly creating a Places instance... however, that is happening after the println in getInitialView.
how do I go about getting the iniatlised Places instance back to getInitialView?
  • I assume makeRequest() is a wrapper around makeWebRequest(), and that you're using setPlacesByLocation as makeWebRequest's callback.

    That won't work, bc as the doc says:

    Web requests are asynchronous. The supplied response callback method will be called when the request returns.

    It's no different than XMLHttpRequest in js. Note that Monkey C has no equivalent to js promises or async methods.

    So you can't call makeWebRequest with a supplied callback function and expect the callback to be called before makeWebRequest returns, therefore your API response won't be available for getInitialView() (since you obviously can't control when getInitialView() is called). You wouldn't want it to work that way in any case, as the user shouldn't have to wait for possibly several seconds for the app's initial view to appear.

    You need to create your initial view without a Places instance (have it display some placeholder / "waiting for data..." message / progress bar, if necessary). The callback should create the Places instance and inform the initial view that the data is ready.

  • For a real device you need to do

    Position.enableLocationEvents(Position.LOCATION_CONTINUOUS, method(:onPosition));
    to turn on GPS
    Look at the websample in the sdk

    You don't want to call your callback until the callback for Communications.makeWebRequest() has been called

    You really don't want to do this in getInitialView and maybe in the initial view.