I'm trying to make a very basic pedestal app to display a list of items, or a text message if the list is empty.
I thought what I wanted was :
- a data model where [:root :items] would be my list of items
- a template function for the page ([:root])
- a static template function for the empty list
- a dynamic template function for a list with elements
- at the start of the application, send a message that will initialize the list to be empty
- in rendering, respond to :
[node-create [] :map]
by doing ... nothing ?[node-create [:root] :map]
by rendering the template for the full page[node-create [:root :items] :map]
by adding the template for the empty list
To be clear, what I want to display in the end would be (without elements)
<html>
<div>My list</div>
<p>There is nothing in the list</p>
</html>
and when there is something in the list :
<html>
<div>My list</div>
<ul>
<li>item1</li>
<li>item2</li>
</ul>
</html>
Am I on the right track here ?
I'm stuck at initializing the data model to be what I want. The closest I got is this :
;; behavior.clj
(defn init-root-transform [old-value message]
{})
(defn init-items-transform [old-value message]
[])
(def example-app
{:version 2
;; :transform [[:set-value [:greeting] set-value-transform]]})
:transform [[:bootstrap [:root] init-app-transform]
[:bootstrap-systems [:root :items] init-items-transform]
]})
;; start.cljs
... skipped...
(app/begin app)
(p/put-message (:input app) {msg/type :bootstrap msg/topic [:root]})
(p/put-message (:input app) {msg/type :bootstrap-systems msg/topic [:root :items]})
The problem is that, this way, I get a data model with a single :root node containing the value {:items [] }.
It might sounds like a very silly question, but are those two data models the same ?
[:root :systems] => []
[:root] => {:systems []}
And when I boot my application, the generated rendering deltas are :
[node-create [] :map]
[node-create [:root] :map]
[value [:root] nil {:items [] }]
I don't think this is suitable for rendering my list of items, is it ?
UPDATE :
@solussd implied that the two datamodels are the same ; however, when the following delta is generated :
[value [:root] nil {:items []}]
I still can't handle it. If I add a rendering config like this :
[value [:root :items] render-items-list]
Then the render-items-list
function is not called.
If I add a rendering config like this :
[value [:root] render-root]
Then the render-root
function will be called, but obviously, not with the proper 'path', and I suppose it would also be called when any other change to the ':root' element in the data model is changed.
Any idea how I can fix that is welcome...
Yes, those two datamodels are the same.
The node-create and value deltas are sufficient to send the sequence of items to your renderer, but you're rendering granularity is the whole list of items.
Your render config might look like this:
If you wanted to use a template for each item in the list, e.g.,
<ul template="list-item" fields="id:id,content:item"/>
in the html template file), you might want to output deltas at the individual list item level and probably have them be keyvals in a map, e.g. a model like:
{:root {:items {:1 <item> :2 <item> ...}}}
.Hope this helps.