Invalidate Data / Redraw input fields


#1

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?


#2

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.


#3

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?


#4

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


#5

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