Invalidate Data / Redraw input fields

Hi, we are using often forms and input fields which will store the data by change event helper.

'change #foo' ....

We have added validation checks as hooks and meteor functions for the collection, so that we just need to push the entered data to them like:

meteor.call(‘foo.update’, e.target.value)

Lets say, the value is rounded on server function before stored.

Now:

  1. Entering 123.456
  2. foo.update => round => 123 => stored to mongo
  3. now we got a reactive data update >= template is renewed and input field has content 123

Next:

  1. Entering: 123.32345
  2. foo.update => round => 123 => stored to mongo
  3. now we DON’T get a reactive data update, because it was the same value stored to mongo
  4. template is NOT renewed => input field stayswith content 123.32345

Content is now DISLINKED to db values

If you close / open once the template, the values are correct loaded.

By now we just do a addtional col.find() in the event procedure after update and setting value back to e.target.value.

But this is boring :frowning:

Q: Any suggestion how to easy make sure that we get rerendering of fields in any case after updatings?

You can indicate in result of that meteor.call state when nothing was updated and act according it in callback . Callback is optional meteor.call parameter.

Hi @shock, thanks for that hint but as I said, there are also collection hooks / methods as well we are using to validate the data before storing them.

I mean, the template is bound to those fields like

<input value="{{foo}}" ...

In that case there should be / is already? an easy way to make sure that those fields have to be checked after change.

Maybe something like: e.refresh or Blaze.invalidateElement(e)

Anyone with knowledge about things like that?

Is there a reason you cannot save the original number and use hooks/helpers to convert for presentation?

Hi Rob ( @robfallows ),

there is no technical reason, currently we are doing it like that:

Template.Foo.events({
  'change .value-bar': function(e) {
    var input_value = e.target.value;
    // update document -> will self check for valid values
    if (this.update({ bar: input_value })) {
       // on success we have to re-read last value from collection
       var new_bar = Col.findOne('_id:' + this._id).bar;
       // make sure to have that value also in templates field
       e.target.value = new_value;
    } else {
       // reset value in any case with last template data value
       e.target.value = this.bar;
    }
  }
 }

But as you can see, if this has to be done for a number of fields and templates, it is a lot of code copy and paste.

For my opinion, this should work like

Template.Foo.events({
  'change .value-bar': function(e) {
    var input_value = e.target.value;
    // update document -> will self check for valid values
    this.update({ bar: input_value });
  }
 }

That means, whatever the collection processing will do, it should be possible to signal the invalidation of collections data.

Let’s do it in a collections transform

Col = new Meteor.Collection("col", {
  transform: function (doc) {
    doc.update = function (values) {
      if (values ... whatever check) {
        .....
      }
      
      // Now I know, that this document should be re-read by collection
      // I mark it as invalid
      METEOR.INVALIDATE_DOCUMENT(this);
      return true;
    }
  }
});

Maybe that already exist ??? I don’t know, otherwise I would like to have something available like that.

Tom