1

let's say I'm building a Kanban board using LWC, and I have the following markup:

<template>
    <div class="kanban-container slds-border_left slds-p-around_medium">
        <template for:each={lanes} for:item="lane" for:index="i">
            <c-kanban-lane key={lane.stage} lane-data={lane} lane-index={i}>
                <template for:each={cards} for:item="card" for:index="i">
                    <template if:true={cardInLaneStage}>
                        <!-- Render only cards into this slot that are in the current stage -->
                    </template>
                </template>
            </c-kanban-lane>
        </template>
    </div>
</template>

How would I be able to get cardInLaneStage to evaluate to what I need it to, which is essentially card.stage === lane.stage? From what I read in the docs, the LWC engine does not allow in-markup computing of expressions, so I'd need to use a getter in my JS file to compute something. BUT, how could I pass the relevant context in order to compute this expression? Is something like this just not possible in LWC at this point? Should I re-think the way I'm trying to build something like this?

Please let me know if anyone needs additional clarification to understand what I'm trying to do here.

Thanks in advance.

  • I suppose I could just change the data structure so I can access lane.cards, but this problem in general seems like a pretty annoying limitation. – no_stack_dub_sack Apr 29 at 21:35
1

I think the answer is not in LWC's syntax, but in forming your architecture properly. One of the things you can do is to create a subcomponent for a lane, then you can compute all you want. For example:

Existing component

... some code
<c-kanban-lane key={lane.stage} lane-data={lane} lane-index={i}>
    <template for:each={cards} for:item="card" for:index="i">
        <c-card item={card} stage={lane.stage} ></c-card>
    </template>
</c-kanban-lane>
... some more code

New Card Component Markup

<template>
... some code
    <template if:true={cardInLaneStage}>
        Something  
    </template>
... some more code 
</template>

New Card Component JS

...some code
@api stage;
@api item;

@api
get cardInLaneStage() {
  return (item.stage === stage);
}

...some more code

This way you can evaluate in context... And also raise events or detect clicks in a cleaner way.

  • Thanks for your answer. To clarify, I always intended to render a subcomponent where the comment is my OP, if that's what you mean about raising events and detecting clicks in a cleaner way.However, the issue is how to get only the cards we want rendered. This solution will work, but correct me if I'm wrong, this will still render a card component for each card in each lane. It may not show the markup, but LWC will still render it's wrapper, empty though it might be. I'm not sure how big of an issue this is, but it seems like there will still be some unnecessary stuff in the dom. – no_stack_dub_sack Apr 30 at 0:37
  • So what? does an empty div matter? – Sebastian Kessel Apr 30 at 0:38
  • That said, I agree with your overall statement. Perhaps my original solution just isn't the best. If each lane has a property named cards, that has only the cards in it's lane, that might be a better approach. So to my original question, though, to your knowledge, is there no way of passing information like this to a function in your JS controller from the markup? – no_stack_dub_sack Apr 30 at 0:41
  • > So what? does an empty div matter? -- probably not so much – no_stack_dub_sack Apr 30 at 0:42
  • No, not that I know of. But there are patterns, like the one I described (or others, depending on use case) , to mitigate the needs – Sebastian Kessel Apr 30 at 0:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.