This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

LAUNCHXL-F28379D: GUI Composer: binding in javascript from target to model

Part Number: LAUNCHXL-F28379D


Tool/software:

I can successfully display a variable g_tempC coming from the microcontroller, in GUI Composer Application v3 thermometer widget with the value property binding set from pm and g_tempC. I have a second thermometer widget with id thermometer_1 that I want to display Fahrenheit. To that end, I cannot get the bindingRegistry example to work: 

bindingRegistry.bind('widget.thermometer_1.value', 'streaming.g_tempC',
     value => { value*9/5 + 32; }, // getter: model -> target (C → F)
     value => { (value-32)*5/9; }  // setter: target -> model (F → C)
);

I have <script type="module" src="./app_0.js"></script> at the top (third line actually) of my index.gui file.

I get an error saying the "Binding streaming.g_tempC does not exist". I've also tried "pm.g_tempC". I'm going off the scant example in the manual. So how do I correctly implement the bindingRegistry.bind example ? And then, do I need to fill in the value property of the Fahrenheit thermometer, and bind to something there too? I'm leaving it blank right now and otherwise don't know what to specify there.

  • Hi Erik, 

    In your code example

    ,'streaming.g_tempC'

    should be 

    ,'pm.g_tempC'

    There is a bit more information on different "data models" here: 

    4.2. Target programming — GUI Composer Getting Started

    4.2. Target programming — GUI Composer Getting Started

    pm -> Program Model : I.e. a data model where symbols from .out (ie. generated from CCS project) are used as "keys" for data  

    Streaming -> streaming model that is typically used for serial communication (i.e COM or UART), there are few built-in schemes for how data is structured (e.g. JSON) but a custom protocol parser can be developed as well. 

    The configuration of Transport+parser+data model is controlled through connection manager html tag. some examples are listed in component help

    GUI Composer Component Help

    However, since you have one widget working, you are most likely past this step. If you do use bindRegistry.bind method then you should leave the widget property page configuration blank (which is what you showed in the picture). If you have both styles of bindings created then there can be multiple events triggering and causing issues. 

    It does seem like you tried pm.g_tempC which is what I would have expected to work, then there might an issue with syntax. I have copied/pasted text in the past and some characters were not parsed correctly by JavaScript interpreter. 

    What I would suggest is to run the app by pressing play button, new tab should open, then open Browser Developer Tools and then try to open (CTRL+SHIFT+P) app_0.js if browser dev tools can't find it then there is mostly likely some parsing error. If you can open the file, try setting a breakpoint on the getter function. You may need to split example into multiple lines to make setting a breakpoint easier. Then connect to HW and see if you hit a breakpoint. If it doesn't I would also check to see if there are any errors in the "Console" tab of Dev Tools. 

    Martin

  • I was able to debug and hit breakpoints, but I don't know what to inspect when I do. I'm not well versed in debugging web apps. It is really strange that I don't get an error, but the thermometer_2 just displays 0. I can see a 0 value debugging, too. I was hoping to confirm whatever 'pm.g_tempC' resolves too, but 

    Moreover, when I add the line bindingRegistry.bind('thermometer_2.value', 'pm.g_tempC'); in an otherwise working application, all the data becomes blank/0. To confirm, this is expected to work, correct?

    Do you think its a limitation of xds communication, whereas the demonstration of bindingRegistry.bind(‘widget.gc_widget_led.on’, ‘streaming.led_on’); uses streaming? By the way, why does that line have the prefix widget in the first argument? 

    Is there anything specific I can try to do when debugging? 

    By the way, I had rephrased this same issue in another post, apologies for the double up 

  • Hi Erik, 

    I did not quite pay attention to starting file that you used to create a binding using javascript. file->New -> Application javascript has a slightly out of date syntax (I'll file a ticket that we will need to resolve). However, all v3 component library projects by default include index.js file. It is automatically included by index.gui file thus you do not need add it there. 

    Index.js has a more accurate template with necessary content functions and synchronization elements. Below is a code snippet that I used to confirm that I was able to see widget updates to same variable that was connected through property page binding and programmatic binding using javascript. In my case the program file that I created has a 'counter' global variable. The bindingregistry call is the same, but there are couple of extra function calls (starting with await) to make sure that data models are fully initialized (widget is type of a data model similar to pm). 

    My apologies for the confusion. 

    Martin

    **/

    // Example code:
    //
    (async () => {
    // /* Wait for widget and target models to be ready */
    await bindingRegistry.waitForModelReady('widget');
    await bindingRegistry.waitForModelReady('pm');
    //
    // /* A simple computed values based on simple expression */
    // bindingRegistry.bind('widget.id.propertyName', "targetModelId.targetVariable == 1 ? 'binding is one' : 'binding is not one'");
    //
    // /* A custom two-way binding with custom getter and setter functions */
    // /* (setter is optional and getter only indicates one-way binding) */
    bindingRegistry.bind('widget.thermometer.value', 'pm.counter',
    value => {
    return value*5/9 + 32;
    }, /* getter */
    value => {
    return (value-32)*9/5;
    } /* setter */
    );
    //
    // /* 1 to n bindings */
    // bindingRegistry.bind('widget.date.value', {
    // /* Dependant bindings needed in order to compute the date, in name/value pairs */
    // weekday: 'widget.dayOfWeek.selectedLabel',
    // day: 'widget.dayOfMonth.value',
    // month: 'widget.month.selectedLabel',
    // year: 'widget.year.value'
    // },
    // /* Getter for date computation */
    // function(values) {
    // /* compute and return the string value to bind to the widget with id 'date' */
    // return values.weekday + ', ' + values.month + ' ' + values.day + ', ' + values.year;
    // }
    // );
    })();