Changing text on drawable within a response callback after a web request.

Hi! I'm trying to get some data from a web service, and update a label / textarea with some returned values.

I've this code in a view that uses some random URL that simply returns some JSON and I correctly got the data, but I cannot update the label text within the "onReceive" method, while I can correctly do that in the "onLayout".

drw in both cases is an Object, and no error is risen, it simply does nothing, I also tried to simply change the bg color, but the one in onLayout works while the one in onReceive also in this case does nothing.

What I'm doing wrong here?

(Note that the 2 elements are a label and a text-area, but also switching them has no effect, the one in onLayout always works, the one in onReceive doesn't)

Thanks!

    function onReceive(response as Lang.Number, responseData as Null or Lang.Dictionary or Lang.String) as Void {
        var test = responseData[0]["login"];
        var drw = self.findDrawableById("mylabel") as Text;
        drw.setBackgroundColor(Graphics.COLOR_RED);
        drw.setText(test);
    }

    // Load your resources here
    function onLayout(dc as Dc) as Void {
        setLayout(Rez.Layouts.myViewLayout(dc));

        var url = "https://api.github.com/users/hadley/orgs";
        var params = null;

        var options = {
            :method => Communications.HTTP_REQUEST_METHOD_GET,
            :headers => {
                "Content-Type" => Communications.REQUEST_CONTENT_TYPE_URL_ENCODED,
            },
        };

        var onReceiveCallback = method(:onReceive);
        Communications.makeWebRequest(url, params, options, onReceiveCallback);

        var drw = self.findDrawableById("BlockOfText") as TextArea;
        drw.setBackgroundColor(Graphics.COLOR_GREEN);
        drw.setText("text changed in 'onLayout'");
    }

  • What does onUpdate() look like? If it doesn't call View.onUpdate(), then your layout elements won't be updated on the screen. Furthermore, you need to trigger onUpdate() (using WatchUi.requestUpdate()) in onReceive(), since you have new data to be displayed.

    This is what I would suggest:

    var responseText = null;
    function onReceive(response as Lang.Number, responseData as Null or Lang.Dictionary or Lang.String) as Void {
        responseText = responseData[0]["login"];
        WatchUi.requestUpdate();
    }
    
    function onUpdate(dc as Dc) as Void {
        // any layout-related calls should appear before View.onUpdate()
    
        if (responseText != null) {
            var drw = self.findDrawableById("mylabel") as Text;
            drw.setBackgroundColor(Graphics.COLOR_RED);
            drw.setText(responseText);
        }
    
        View.onUpdate(dc); // this will render the layout
    
        // any direct dc calls (i.e. not related to the layout) should appear after View.onUpdate()
    }

  • Oh! That's great, thanks, it's my first experience with monkey c / garmin apps so I completely missed the onUpdate part... your suggestion works like a charm! 

    Thanks!

  • In your onReceive callback code you want to check for a response==200, as other wise there was an error while doing the makeWebRequest() and the responseData could be null 

  • Thanks! Yes, I need to add some checks also for the data validity, this was more or less a draft to start taking a look at how things works