Why does widget glance view never update?

I try to add a glance view in the WebRequest SDK sample.

I want to display the received data in the glance view.

The glance view is showing up but the message string in the view is never updated.

But the System.println("message: "+_message); in the onReceive function does print the correct message.

I have tried it with multiple devices in the simulator but somehow it displays always the initial "123" message string.

I have read that the device needs to have liveUpdates true like the fenix6pro.

But it does also not work in the fenix6pro simulator.

Can someone tell me what I do wrong?

WidgetGlanceView.mc:
using Toybox.WatchUi as Ui;
using Toybox.Graphics as Gfx;

(:glance)
class WidgetGlanceView extends Ui.GlanceView {
  hidden var _message as String = "123";
	
    function initialize() {
      WatchUi.GlanceView.initialize();
    }
    
    function onUpdate(dc) {
    	 dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
        dc.clear();
        dc.drawText(dc.getWidth() / 2, dc.getHeight() / 2, Graphics.FONT_MEDIUM, _message, Graphics.TEXT_JUSTIFY_CENTER | Graphics.TEXT_JUSTIFY_VCENTER);
    	 //dc.drawRectangle(0, 0, dc.getWidth(), dc.getHeight());
    }

    //! Show the result or status of the web request
    //! @param args Data from the web request, or error message
    public function onReceive(args as Dictionary or String or Null) as Void {
      System.println("onReceiveGlanceView");
      System.println("args "+args);
        if (args instanceof String) {
            _message = args;
            System.println("args1 "+args);
        } else if (args instanceof Dictionary) {
            // Print the arguments duplicated and returned by jsonplaceholder.typicode.com
            var keys = args.keys();
            System.println("args2 "+args);
            for (var i = 0; i < keys.size(); i++) {
                //_message += Lang.format("$1$: $2$\n", [keys[i], args[keys[i]]]);
                _message += Lang.format("$1$: $2$", [keys[i], args[keys[i]]]);
            }
        }
        System.println("message: "+_message);
        Ui.requestUpdate();
    }
}
WebRequestApp.mc:
//
// Copyright 2015-2021 by Garmin Ltd. or its subsidiaries.
// Subject to Garmin SDK License Agreement and Wearables
// Application Developer Agreement.
//

import Toybox.Application;
import Toybox.Lang;
import Toybox.WatchUi;

//! This app demonstrates how to make web requests through GCM.
class WebRequestApp extends Application.AppBase {

    //! Constructor
    public function initialize() {
        AppBase.initialize();
    }

    //! Handle app startup
    //! @param state Startup arguments
    public function onStart(state as Dictionary?) as Void {
    }

    //! Handle app shutdown
    //! @param state Shutdown arguments
    public function onStop(state as Dictionary?) as Void {
    }    

    (:glance)
    function getGlanceView() {
        var view = new $.WidgetGlanceView();
        var delegate = new $.WebRequestDelegate(view.method(:onReceive));
        return [ new WidgetGlanceView() ];
    }
    
    //! Return the initial view for the app
    //! @return Array Pair [View, Delegate]
    public function getInitialView() as Array<Views or InputDelegates>? {
        var view = new $.WebRequestView();
        var delegate = new $.WebRequestDelegate(view.method(:onReceive));
        return [view, delegate] as Array<Views or InputDelegates>;
    }
}
  • See https://developer.garmin.com/connect-iq/core-topics/glances/

    The Glance Lifecycle section.

    Depending on the device, glances can have live updates or not.  A call to WatchUi.requestUpdate() is ignored on devices without live updates.

    As far as the sim, I see the glances being updated on devices like the 945 that have live updates.

  • Thank you Jim. I have already read this.

    When I go to Devices > fenix6pro > simulator.json

    There I can see "liveUpdates": true.

    But when I try it with the fenix6pro simulator it does still not update the view.

    Same with the fr945.

  • Connect IQ 4.0.7 on macOS 11.6.2 with VS Code 1.63.2

  • I don't see where you are doing the makeWebRequest,  You have a delegate for the glance view, but it will never be used.

    If it's meant to get user input, there is no user input to a glance view.

    I'm running a widget right now and watching the glance.  It has a background service that does a makeWebRequest every 15 minutes and things are running fine with a 945 target.

  • Here is my WebRequestDelegate.mc

    makeRequest() is called in the initialize function.

    The System.println in WidgetGlanceView.mc does print the correct received message. But it seems the Ui.requestUpdate(); after the System.println in WidgetGlanceView.mc does not work?

    //
    // Copyright 2016-2021 by Garmin Ltd. or its subsidiaries.
    // Subject to Garmin SDK License Agreement and Wearables
    // Application Developer Agreement.
    //
    
    import Toybox.Communications;
    import Toybox.Lang;
    import Toybox.WatchUi;
    using Toybox.System;
    
    //! Creates a web request on menu / select events
    (:glance)
    class WebRequestDelegate extends WatchUi.BehaviorDelegate {
        private var _notify as Method(args as Dictionary or String or Null) as Void;
    
        //! Set up the callback to the view
        //! @param handler Callback method for when data is received
        public function initialize(handler as Method(args as Dictionary or String or Null) as Void) {
            WatchUi.BehaviorDelegate.initialize();
            _notify = handler;
            makeRequest();
            return true;
        }
    
        //! On a menu event, make a web request
        //! @return true if handled, false otherwise
        public function onMenu() as Boolean {
            makeRequest();
            return true;
        }
    
        //! On a select event, make a web request
        //! @return true if handled, false otherwise
        public function onSelect() as Boolean {
            makeRequest();
            return true;
        }
    
        //! Make the web request
        private function makeRequest() as Void {
            System.println("makeRequest");
    
            _notify.invoke("Executing\nRequest");
    
            var options = {
                :responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON,
                :headers => {
                    "Content-Type" => Communications.REQUEST_CONTENT_TYPE_URL_ENCODED
                }
            };
    
            Communications.makeWebRequest(
                "https://jsonplaceholder.typicode.com/todos/115",
                {},
                options,
                method(:onReceive)
            );
        }
    
        //! Receive the data from the web request
        //! @param responseCode The server response code
        //! @param data Content from a successful request
        public function onReceive(responseCode as Number, data as Dictionary?) as Void {
            System.println("onReceive");
    
            if (responseCode == 200) {
                _notify.invoke(data);
            } else {
                _notify.invoke("Failed to load\nError: " + responseCode.toString());
            }
        }
    }

  • That will never be used when you are just running the glance.  A glances view doesn't allow any user input.  You can move the glance up and down and go to full screen, but that's it, and none of those are passed to the glance view,

  • I am sorry Jim but I dont understand. The makeRequest(); in the initialize function seems to work. It prints System.println("makeRequest"); and System.println("onReceive"); from WebRequestDelegate.mc in the console when the glance view starts.

    And than it also prints correctly the System.println("message: "+_message); from WidgetGlanceView.mc.

    But than it does not update the glance view.

    Is this totally wrong? How can I make the request and than show the result in the glance view when it starts up?

  • Initialize will run as you did a "new" on the delegate, but you will never see onMenu or onSelected called when the glance view is running.

    So the makeWebRequest will only run once when you're looking at the glance.

  • Yes I just want that the makeRequest is called once in the initialize function when the glance starts up.

    But I dont need the onMenu and onSelect they are just from the example.

    The glance should start, makeRequest and than show the received data.

    But it does never update the view with the received data from makeRequest in the initialize function.

    makeRequest is running once correctly on start up but it does not display the correct received message.