Reactive helper input value behaviour in dynamic templates


#1

I am using a helper for getting a reactive variable into a dynamic template:

<template name='integer_element'>
    {{#with data}}
        <div class='css_integer_element_wrapper'>
            <input class='css_integer_input js_input_element' value='{{this.value}}'>
        </div>
    {{/with}}
</template>

when data and accordingly this.value changes the display value in the input element is supposed to change.
For some reason this does not work when the initial value is an empty string.

If the initial value is lets say 123 and i manually change the input to 124 then on data change the new value gets displayed and 124 is being discarded but when the initial default value is empty string and i change it to 124 then after data change the input element still displays 124.

Any idea how to overcome this?


#2

Can we see your helper code?


#3

Sure. The data comes from nested dynamic templates so its a bit tricky:

This is the helper for the integer_element template:

Template.integer_element.helpers({
data: function () {
return this;
}
});

which in turn gets data via this:

{{>Template.dynamic template = this.template data=this}}

from a parent template.

Logging this.value in the helper always shows the correct value yet the input element does not update accordingly.


#4

Your description towards bottom of initial post is illogical, but I bet on types being wrong, that is, string is no number, although clearly even then there would be underlying bug or mechanism at work.


#5

Thanks for the feedback. Underlying mechanism describes it pretty well I believe.

I found a workaround for my problem but there must be a more elegant solution to it. I put together a bit more of my code to explain my question better (hopefully).

My html looks like this:

{{> form}} {{#with data}}
    {{#if data_available}}
    {{#each this.rows}}
         <div class="css_form_wrapper">
    {{>Template.dynamic template=this.template data= this}}
         </div>
    {{/each}}
    {{/if}}
    {{#unless data_available}}
        <div>
            Loading Data
        </div>
    {{/unless}}

    <div>
        <button class='button'>Refresh</button>
    </div>
{{/with}}
{{#with data}}
{{/with}}

The if / unless part is just there so that when I change data_availability the element templates get destroyed and when I have data i can make sure that the default value in the input element gets reloaded because the template gets rendered.
Without that condition the data helpers get executed and the data the template has is the backend data but the input element will still show whichever value the user entered (As far as I understand because it gets stored in the DOM, right?, but to be honest I dont understand it :slight_smile: )

Is there maybe a better way to rerender a specific template?

This is the javascript to it, it simulates a backend call for the data.

var form_tracker = new Tracker.Dependency;
var backend_tracker = new Tracker.Dependency;
var data_available = true;

Template.form.helpers({
data: function () {
var data = _readData();
return data;
},
data_available: function () {
return data_available
}
});

Template.form.events({
‘click .button’:function(){
data_available = false;
_readBackendData();
form_tracker.changed();
}
});

var _readData = function () {
form_tracker.depend();
backend_tracker.depend();
if(backend_tracker.data != undefined) {
return backend_tracker.data
} else {
return {rows: [{‘template’: ‘element’, ‘value’ : ‘no data initially’}]};
}
};

var _readBackendData = function () {
Meteor.setTimeout(function() {
backend_tracker.data = {rows: [{‘template’: ‘element’, ‘value’ : 123}, {‘template’: ‘element’, ‘value’ : ‘’}]};
backend_tracker.changed();
data_available = true;
}, 800);};

Template.element.helpers({
data: function () {
var data = this;
return data;
}
});

This workaround becomes super tedious if just parts of the template get refreshed so I hope somebody can point me in a more elegant direction. Thx