asynchronous processes and variables and errors

Lets see example

var global gV;

function classA_setThemeParams(colour)

{

  gV= col;

  ....

}

function onLayout(dc)

{

classA_setThemeParams();

}

function onUpdate(dc)

{

for(i...)

{

    //something external fe. backgroung call classA_setThemeParams during the loop

    drawables(i).draw(dc);//samewher in drawables there is dc.setColor(gV,gV);  <----------------------------------- from time to time error, why?

}

Error Name: Symbol Not Found Error

Error Name: Invalid Value

Why this happen?

gV should be handle an point to  value

this example  show that

- sdk makes "local var" from global instead of taking value from def every time

- during operation = sdk change handle to object

  • although you might think it would be logical to always have at least one onLayout before an onUpdate, you can not expect that onLayout occurs before onUpdate so your global will be null and null is an invalid value for the setColor call

    initialise your global in initialize function

  • Sorry but has to be any rules, according the documentation

    https://developer.garmin.com/connect-iq/api-docs/Toybox/WatchUi/View.html#onUpdate-instance_function

    View objects also handle the life cycle of each app, which varies depending on the app type:

    Watch Faces

    onLayout()onShow()onUpdate()

    so I can expected that onLayout is call before onShow and onUpdate at least once

  • You should be able to expect that onLayout is called before onShow and onShow is called before onUpdate. There may have been issues in the past, but those would all have been bugs.

    There has never been a guarantee when view functions (onLayout, onShow, or onUpdate) will get called in relation to compute when dealing with a data field, but we should follow the guarantee set forth in the docs for view functions.

  • yes, I know about this limitation in df (I've already done 2 DFs), but not in wf and app

  • well you can do 2 things:

    - create a bug report for the device where you get the error and potentially the order isn't respected

    - follow my advice and intialize your global var in your intialize function

    or you can do both

  • A. I have background process which call App.onBackgroundData which use code:

    setProperty(any_key,null);//to protect before peak memory (I've notice that system maybe makes "copy" an there is peak

    setProperty(any_key,any_data);

    B. In view every second/minutes onUpdate/onPartialUpdate is called asynchronous.

    Question: is safety  to call getProperty(any_key) in B. Is system secured and I can be sure that when I'm reading "big data" it isn't set to null in the same time during the app?

    I'm still have strange errors from time to time, I haven't protected for it because it's the same object app and it should make queue for such requests.

  • May I ask for answer because i don't know if I should make refactoring...

  • If I'm understanding your question correctly, you're asking whether onBackgroundData() and onUpdate()/onPartialUpdate() can execute at the same time in the main process?

    My understanding would be "no", but if I'm wrong about that, wouldn't it be very easy to handle this edge case when you call getProperty()?

    function onUpdate() {
    
        // e.g. of original code
        x = getProperty("backgroundData");
    
        // e.g. of new code
        var x_tmp = getProperty("backgroundData");
        if (x_tmp != null) {
            x = x_tmp;
        }
        //...

    Furthermore, why do you need to read it back inonUpdate()/onPartialUpdate() with getProperty() at all? You already received it with onBackgroundData, can't you just save it to a member variable or a global variable? That way you don't have to worry about null checks. I don't see why getProperty() needs to be called except when your watchface starts up (in appbase.initialize() or onStart()), assuming that the data needs to persist.

  • is let in "let x_tmp" keyword I don't ir?

    1. App.onBackgroundData is called by background process  I don't know when system call onTemporalEvent

    2. in Back.onTemporalEvent  I call  COM.makeWebRequest I don't know when system call App.onBackgroundData  with rsponse

    my error is strange: there is dictionary in property, when I save it I know that data are "good , complete and consistent" when I read it it's look like some key are from previous data for example I save

    key_1=gps_invalid

    key_2=gps_lat=null

    key_3=gps_lon=null

    when I read using getProperty(I can't using global its' background, there is no view for example, so I have to save data)

    key_1=gps_valid

    key_2=gps_lat=null

    key_3=gps_lon=gps_lon

    it's very difficult to test it because error is on users's device, sim is fast, so I ask about protection from such situation.  Is saving property is "atomic" and when another process call getPropery app response after setProperty.

  • I edited my code to change "let" to "var". Sorry.

    I'm not an expert on CIQ background processes, but I thought that App.onBackgroundData() runs in the *main* process, as implied by the docs.

    developer.garmin.com/.../AppBase.html

    onBackgroundData(data)

    Handle data passed from a ServiceDelegate to the application.

    When the Background process terminates, a data payload may be available. If the main application is active when this occurs, the data will be passed directly to the application's onBackgroundData() method. If the main application is not active, the data will be saved until the next time the application is launched and will be passed to the application after the onStart() method completes.

    Parameters:

    See Also:

    Since:

    2.3.0