Replacing visualforce conditional rendering formulas in LWC

conditionalhtml-template-directivesvisualforce

so I'm migrating a visualforce component into LWC. In that component, there is a table rendered, and a lot of columns are rendered differently depending on data field values and/or some other condition regarding a property in the controller. This is, for example, something I have to convert:

            <apex:column headerValue="{!$Label.erpvs__consultastockproductos_2}" styleClass="td_number" headerClass="td_number">
            <apex:outputPanel rendered="{!producto.saldoStockFisico.Cantidad__c != 0 && mapProductoHasUbicaciones[producto.producto.id] == true}">
                <apex:commandLink onclick="abrirDetalle4('');setarValor('{!producto.producto.id}');" action="{!cargarPopup4}" rerender="refresh7,refresh8" ><apex:outputField value="{!producto.saldoStockFisico.Cantidad__c}" /></apex:commandLink>
            </apex:outputPanel>
            <apex:outputField value="{!producto.saldoStockFisico.Cantidad__c}" rendered="{!producto.saldoStockFisico.Cantidad__c == 0 || mapProductoHasUbicaciones[producto.producto.id] == false}"/>
        </apex:column>

The outputPanel condition, for example:

<apex:outputPanel rendered="{!producto.saldoStockFisico.Cantidad__c != 0 && mapProductoHasUbicaciones[producto.producto.id] == true}">

This outputPanel should be rendered based on two things. The value of the "Cantidad__c" field of the item being rendered, and also, if the value of the "mapProductoHasUbicaciones" property (defined in the apex controller) corresponding to that item, is true.

In my LWC, I did not use a lightning-datatable, but I wrote a normal table using lsds table classes. For each item, i render a row, and I can define if:true statements for simple conditions but I can't make a combination of item field values and conditions related to properties of my javascript controller.

So for example, if I have this in my HTML:

      <td>
           <!-- if ammount != 0 && mapHasUbicaciones[producto.id] == true -->
           <a href="#" onclick={openPopup4}>{producto.fisico}</a>

           <!-- if ammount == 0 || mapHasUbicaciones[producto.id] == false -->
           <div class="slds-truncate">{producto.fisico}</div>
      </td>

If both conditions were related to a field of the item, I could easily add a boolean getter in my custom js class for the items, and thats that. But, the second condition complicates the matter. I can't make a getter in my JS controller because I can't access my item field value, and I can't make a getter in my item js class because I can't access the map (that is located in my JS controller).

So is there a way to access the map from my item's js class, or access my item from my js controller? A getter can't receive parameters. So how could I identify which item it is?

Best Answer

In LWC, we don't get "expressions" in the same sense as we do in Aura. So, you typically just modify the data so that the combined expressions now exist as properties in your data. For example:

@wire(myMethod,{}) myMethodHandler({data, error}) {
  if(data) {
    this.displayList = data.map((record) => 
      ({ ...record, 
         itemHasUbicaciones: record.Cantidad__c && this.productMap.has(producto.id) 
      }))
  }

Once you've calculated the values, you can then proceed to use those values as normal:

<a href="..." if:true={producto.itemHasUbicaciones}>

In general, this is pretty easy to do, it just takes some practice getting used to calculating the desired properties in JavaScript rather than in the template.