Skip to content

Order of reactive computations changed by isolateValue #1

@steph643

Description

@steph643

Not using isolateValue :

<!-- Context should contain a field 'text' -->
<template name="paragraph">
    {{#if th_containsBadWords}}
        <p>You are too young to view this paragraph.</p>
    {{else}}
        <p>{{th_translatedText}}</p>
    {{/if}}
</template>

Template.blogPost.th_containsBadWords = function() {
    return MySafeText.containsBadWords(this.text);
}

Template.blogPost.th_translatedtext = function() {
    return i18n.translate(this.text);
}

Suppose the following course of action:

  1. Initially, 'text' does not contain any bad word and is displayed normally.
  2. Then 'text' is updated in the database with a value containing a bad word.
  3. Because th_containsBadWords and th_translatedtext are reactive computations depending on 'text', they might both be triggered.
  4. But because th_containsBadWords has been declared first, it is executed first, removing the very need of calling th_translatedText (which is good).

Using isolateValue :

th_containsBadWords can benefit from isolateValue, for example to avoid refreshing the {{if}} block every time 'text' is changed with an additional bad word.

Template.blogPost.th_containsBadWords = function() {
    return isolateValue(function() { MySafeText.containsBadWords(this.text) });
}

This is a huge progress over the previous version.

However there is a drawback: it seems isolateValue has changed the reactive computation order.

Here is what I see when using the new th_containsBadWords:

  1. Initially, 'text' does not contain any bad word and is displayed normally.
  2. Then 'text' is updated in the database with a value containing a bad word.
  3. Because th_containsBadWords and th_translatedtext are reactive computations depending on 'text', they might both be triggered.
  4. th_translatedText is called first, which is useless.
  5. th_containsBadWords is called next, hiding the text we have just translated.

We can put things back in order by changing also th_translatedText like this:

Template.blogPost.th_translatedtext = function() {
    return isolateValue(function() { i18n.translate(this.text) });
}

But this looks ugly.

Any idea? Am I wrong somewhere? (notice that I use Meteor 0.8.3.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions