mikado icon indicating copy to clipboard operation
mikado copied to clipboard

for with if example gives js error

Open john5000 opened this issue 5 years ago • 4 comments

I'm trying to do a template with a "for" that has an "if" within it and can't get it to work, gets an error. I found the example on the readme page is very similar and gets the same error.

Example conditional branch from README.md that gives error:

<main>
  <title>{{ data.title }}</title>
  <tweets for="data.tweets">
    <section if="data.content">{{ data.content }}</section>
  </tweets>
</main>

Full code to run:

<script src="mikado.debug.js"></script>
<div id="app"></div>
<template id="tpl">
<main>
  <title>{{ data.title }}</title>
  <tweets for="data.tweets">
    <section if="data.content">{{ data.content }}</section>
  </tweets>
</main>
</template>

<script>
var data = {
    title: "Some title",
    tweets: [
        {content: "Text1"},
        {content: "Text2"},
        {content: "Text3"},
    ]
}
var view = new Mikado(Mikado.compile('tpl'));
view.mount(document.getElementById('app'));
view.render(data);
</script>

Error is: VM14:3 Uncaught TypeError: Cannot set property 'hidden' of undefined

Code generated:

(function anonymous(p, s, data, index, view) {
    "use strict";
    var self, v;
    if (true) {
        self.hidden = false;                 <----- self was never set, so gets error here
        self = p[1];
        v = data.content;
        if (self._text !== v) {
            self._text = v;
            self.nodeValue = v
        }
        ;self = p[0]
    } else
        self.hidden = true
}
)

Mikado 0.7.57

john5000 avatar Jan 27 '20 18:01 john5000

Hello thanks for the detailed report. It will be fixed.

ts-thomas avatar Jan 29 '20 10:01 ts-thomas

Is there a workaround for this?

Edit: For now I have replaced if="test" with if="(self=p[0]) && test" or whatever the "correct" p index is, but I have no idea if this is at all doing the right thing. But I'm curious if this is supposed to do much other than set the "hidden" attribute on the nodes?

sqwishy avatar Jun 16 '21 16:06 sqwishy

Interesting workaround you used. Might work. The index number of p is index of the element (as in childElements).

Example:

    <div>
          <div>{{data.name}}</div>
          <div>{{data.location}}</div>
    </div>

The data.name is referenced by p[0] and data.location is referenced by p[1].

Unfortunately, the "if=" merely sets the "hidden" attribute.

Other work around (without using if= at all), use some variation of: style="display: {{test?'block':'none}}"

john5000 avatar Jun 17 '21 07:06 john5000

I don't want nodes that failed the condition to end up in the document at all.

I spend some time trying to figure out what the behaviour is for for="data.variant" to see if that's closer to what I want but it's pretty freaky.

  • If the variant property is null or undefined or whatever then the node is rendered using data from a previous item in the view/store thing -- so for="data.variant || []" kind of works but I don't know what side effects that has.
  • Extra nesting is required between nodes using for and your template when you have multiple nodes using for even if you only want one of them to pass. In the following, the for="data.bar || []" is never evaluated, even if the first for does not produce any nodes.
    <template id="does-not-work">
      <div for="data.foo || []"></div>
      <div for="data.bar || []"></div>
    </template>
    

I also don't know how it might affect refreshing. I'm pretty discouraged by this so I'm probably not going to spend any more time on it.

sqwishy avatar Jun 17 '21 19:06 sqwishy

Is there a workaround for this?

Without conditions library is useless😒

caracal7 avatar Feb 23 '23 08:02 caracal7

Is there a workaround for this?

Without conditions library is useless😒

Do you have an example code? I am using js="a && b || c" as my workaround.

Dan-Do avatar Feb 28 '23 05:02 Dan-Do

The whole include feature was redesigned in Mikado v0.8.x

ts-thomas avatar Jan 05 '24 13:01 ts-thomas