Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lists of children can only be the last child of an element #2

Open
garrett-hopper opened this issue Jan 21, 2018 · 13 comments
Open

Lists of children can only be the last child of an element #2

garrett-hopper opened this issue Jan 21, 2018 · 13 comments

Comments

@garrett-hopper
Copy link

In Rum, I could have:

[:div
  [:h1 "alpha"]
  (map #(identity [:h1 (str %)]) (range 10))
  [:h1 "beta"]]

However, in Prum, "beta" doesn't show up. Everything works as expected if the map list is moved to the bottom.

@roman01la
Copy link
Owner

I’ll look into this later. But it could be also an issue in Hicada compiler which Prum adopted recently. If you could try to compile the snippet with Hicada directly and report back it would help to identify the source of the issue. Thanks.

@roman01la
Copy link
Owner

Oh wait. I just noticed that you have Hiccup inside of map fn. Most likely it is not being compiled. The reason is that Prum/Hicada doesn’t have runtime interpretation unlike Rum/Sablono. Hicada can walk into simple forms like if, let, do, cond, case, etc., but not into other function calls.

Wrap that Hiccup form with prum.compiler/html macro to force compilation.

@roman01la
Copy link
Owner

Is the list of h1’s rendered as expected?

@garrett-hopper
Copy link
Author

The list is being rendered as expected, but anything after it isn't rendered.

@garrett-hopper
Copy link
Author

How about an instance where I want a dynamic number of sub-components in the middle of other elements? (map #(identity (Component %)) (range 10)) Sometimes it doesn't make sense for those components to all be grouped in a div.

@roman01la
Copy link
Owner

A list of components is rendered as expected, bc components use html macro internally.

@roman01la
Copy link
Owner

Could you test now directly with Hicada?

@garrett-hopper
Copy link
Author

Apparently this:

(prum/defc Layout [_]
  [:div
   [:h1 "alpha"]
   (map #(identity [:h1 %]) (range 5))
   [:h1 "beta"]])

Results in this:

<div>
<h1>alpha</h1>
<undefined></undefined>
"0"
<undefined></undefined>
"1"
<undefined></undefined>
"2"
<undefined></undefined>
"3"
<undefined></undefined>
"4"
<h1>beta</h1>
</div>

However, a for works perfectly:

(prum/defc Layout [_]
  [:divA list of co
   [:h1 "alpha"]
   (for [i (range 5)]
     [:h1 i])
   [:h1 "beta"]])

Using map for components works, however it eliminates anything following it:
(No undefined tags, but also no "beta")

(prum/defc Number [i]
  [:h1 i])

(prum/defc Layout [_]
  [:div
   [:h1 "alpha"]
   (map #(Number %) (range 5))
   [:h1 "beta"]])

This does though:

(prum/defc Number [i]
  [:h1 i])

(prum/defc Layout [_]
  [:div
   [:h1 "alpha"]
   (for [i (range 5)]
     (Number i))
   [:h1 "beta"]])

What's very strange is what this results in:
(Using prum.compiler/html)

(prum/defc Layout [_]
  [:div
   [:h1 "alpha"]
   (map #(html [:h1 %]) (range 5))
   [:h1 "beta"]])

Results in:

<div>
<h1>alpha</h1>
<h1>
"0"
<h1>beta</h1>
</h1>
<h1>1</h1>
<h1>2</h1>
<h1>3</h1>
<h1>4</h1>
</div>

@garrett-hopper
Copy link
Author

I'm looking into Hicada now. I'm not entirely understanding how it works though.

@roman01la
Copy link
Owner

Looks like things are messed up here. I’ll take a look closer next week. Don’t worry. Thanks for helping me out with this!

@garrett-hopper
Copy link
Author

Thanks! Let me know if there's anything I can do to help.

@roman01la
Copy link
Owner

OK. So...

  • The first example is an expected behavior, bc you have to wrap Hiccup form with html macro explicitly in such cases.
  • The second one with for works bc Hicada is able to walk into some Clojure forms such as if, when, for, etc., but not function calls such as map as in the prev example
  • Example where beta is missing after (map #(Number %) (range 5)) but works fine with for seems to be a problem within Preact and how it handles iterable collections of child elements. I'll look into it (I maintain a fork of Preact with iterable children support)
  • The last one seems to have the same source of the problem as the previous issue

Now that I know where to look at, I'll dig into Preact and see what can be done there.

@roman01la
Copy link
Owner

roman01la commented Feb 7, 2018

Looks like it has something to do with ClojureScript's collections, not entirely sure yet. But, for example, Preact renders fine Immutable.js persistent collections.

For now the workaround is to use into-array on a sequence of elements

(prum/defc Layout [_]
  [:div
   [:h1 "alpha"]
   (->> (map #(Number %) (range 5)) into-array)
   [:h1 "beta"]])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants