meteor / blaze

:fire: Meteor Blaze is a powerful library for creating live-updating user interfaces
http://blazejs.org/
Other
526 stars 114 forks source link

Bad resolve with template async parameter #470

Open DblK opened 1 week ago

DblK commented 1 week ago

Blaze: 3.0.0 (2.6.1 worked fine but no promise at that time) Meteor: 3.0.2

Since my migration of my application to Meteor 3.0, I figure out that some variable of template seems not to be resolve the way it used to be.

Here is an example :

<template name="Test>
  <!-- Working -->
  {{#if myProp}}
     Yeah!
  {{else}}
    Dooh
  {{/if}}
  <!-- Not working -->
  <div class="base {{#if myProp}}additional-class{{/if}}">
  Content
  </div>
</template>

If I use within blaze :

{{#Test myProp=asyncProp}}

with :

Template.XXX.helpers({
   async asyncProp() {
     return await something(); // return true
   }
})

The template will always display Dooh instead of Yeah. I expected once the resolve had been done, to pass the new value to the template so it can revaluate it and change the display accordingly.

Did I miss something there?

PS: repo to reproduce the issue.

radekmie commented 1 week ago

Could you please provide a reproduction? Ideally a GitHub repo we could clone and run to see it.

DblK commented 1 week ago

I did a quick and dirty new project to demonstrate the issue. Here is the repo.

ddaydd commented 1 week ago

Hi, where is the template "hello" ?

DblK commented 1 week ago

My bad, to quick to make a repo example. Now it should be clearer about the issue.

radekmie commented 3 days ago

So, I checked it out and the issue is rather tricky. The point is that this...

<img class={{x}}>

...translates to...

Template("Template.test", (function() {
  var view = this;
  return HTML.IMG({
    class: function() {
      return Spacebars.mustache(view.lookup("x"));
    }
  });
}));

...which is fine. But if we'd add some text around, like this...

<img class="1 {{#if x}}2{{else}}3{{/if}} 4">

...then it looks like this...

Template("Template.test", (function() {
  var view = this;
  return HTML.IMG({
    class: function() {
      return [ "1 ", Blaze.If(function() {
        return Spacebars.call(view.lookup("x"));
      }, function() {
        return "2";
      }, function() {
        return "3";
      }), " 4" ];
    }
  });
}));

...which is a problem. The thing is that a new instance of Blaze.If is created every time class is executed. That makes it impossible to preserve the __conditionVar which stores the result of the Promise.

I'll think about it and I'd appreciate any ideas!