1

I'm simply trying to display a list of queried Activities here records. Next, I'll add checkboxes to each.

See screenshot here: the Activities card should display the 6 records as seen in the console. I've been at this for several hours. I was able to render same records with lightning datatable, but it doesn't have the look and feel I want (I do like datatable's built-in checkboxes, but I figure I can use slds-checkbox-button or slds-checkbox for that).

enter image description here

Here's my current code


<template>
  <lightning-card title="Activities" icon-name="custom:custom14">
    <ul class="slds-m-around_medium">
      <template for:each={wiredActivities.data} for:item="activity">
          <li key={activity.Id}>
              {activity.Title__c}
          </li>
      </template>
    </ul>
  </lightning-card>
</template>

import {LightningElement, wire} from 'lwc';
import getAllEventActivities from '@salesforce/apex/EventActivities_Ctrl.getAllEventActivities';
export default class EventActivityChecklist extends LightningElement {
  
  @wire (getAllEventActivities) wiredActivities ({data,error}){
    if (data) {
      console.log(data);
    } else if (error) {
      console.log(error);
    }
  }
}

public with sharing class EventActivities_Ctrl {

    @AuraEnabled (cacheable=true)
    public static List<Event_Activity__c> getAllEventActivities() {
      return [SELECT id, Title__c, Type__c 
              FROM Event_Activity__c 
              ORDER BY Type__c ASC];
    }
}
1

You can use @wire in two ways, to a property or a function. You are wiring to a function, not a property.

If you want to use wiredActivities.data you have to use the single variable name as property

@wire (getAllEventActivities) 
   wiredActivities;

This way you have it is returning to a function wiredActivities. In this case you havent set any variable the view can use to display the results, you are only using it in the console.log

@wire (getAllEventActivities) 
  wiredActivities ({data,error}){
    if (data) {
      console.log(data);
    } else if (error) {
      console.log(error);
    }

}

To use it the way you have set data to something in your method and then use that in your view.

2
  • When I use the following, as you suggest, I get same result: it shows the Card Title but no records: @wire (getAllEventActivities) wiredActivities; – Ryan McNeely yesterday
  • Per your second suggestion... I just tried this but got same result: Card Title but no records. @track activityList; if (data) { this.activityList = data; console.log(data); ... In the html: for:each={activityList} – Ryan McNeely yesterday
1

It's helpful to look through Understand the Wire Service. You can return the results to a property or function as CyberJus highlighted and shown in those lwc-recipes linked. Depending on which you do, changes what you reference in your for:each. The following is from the doc and explains what is returned

A private property or function that receives the stream of data from the wire service. If a property is decorated with @wire, the results are returned to the property’s data property or error property. If a function is decorated with @wire, the results are returned in an object with a data property and an error property.

If you return the results to a function, then you're passed an object (with data and errors properties) into your function to handle/execute your logic. You're currently doing this (returning your activities to a function), but your function is not doing anything with data other than console.log so there's no variable that has your list of activities. You need to store the provided information into a variable to reference in your html.

allActivities = [];

@wire (getAllEventActivities) wiredActivities ({data,error}){
    if (data) {
      allActivities = data; //store the returned information in this function
    } else if (error) {
      console.log(error);
    }
  }

Once you've provided your array of events to a variable, you simply reference it in the for:each

<template for:each={allActivities} for:item="activity">

If you decide you want to return the results to a Property

@wire (getAllEventActivities) 
   wiredActivities;

The result is provided to the property (wiredActivities). The information is within data as you're getting it as Salesforce returned it (within the data and error). So, in your html, you need to reference/loop through data within your property (in this case, your list of events)

<template for:each={wiredActivities.data} for:item="activity">
1

You are mixing the direct property wire technique with the method version.

Because you have a method, you need to explicitly store the data somewhere - in the example below, I'm setting it to activities

Then you just need to reference in the iterator in the template.

eg:

<template for:each={activities} for:item="activity">

code:

activities = [];
 @wire(getAllEventActivities)
 getAllEventActivitiesHandler({ error, data }) {
    if (data) {
      this.activities = data;
    } else if (error) {
      console.log(error);
    }
  }
6
  • When I remove .data as you suggest, nothing renders (not even the Card Title as before) and I get the following error: LC {component: "markup://c:eventActivityChecklist", componentStack: "[flexipageEditor:node] > [flexipage:recordHomeTemp… > [aura:expression] > [c:eventActivityChecklist]", action: null, name: "TypeError", message: "Error during LWC component connect phase: [e[jr] is not a function]", …} – Ryan McNeely yesterday
  • Thanks for your help Caspar. I'm not understanding your last comment here. My original syntax failed. – Ryan McNeely yesterday
  • Following gives an Unexpected token error. let activities = []; – Ryan McNeely yesterday
  • Fixed - sorry. no let in the class body! – Caspar Harmer yesterday
  • Thanks Caspar. Unfortunately, after removing "let" from the array variable, same result: Card Title appears but no records show. – Ryan McNeely yesterday
0

We have a list of records! enter image description here

Caspar and CyberJus were right about a lot here. What was preventing their suggestions from working was the li markup I was using. Below, you'll see I changed to span and div. HTML nerds, please explain why ul and li didn't work here; it seems it should have.

In the JS file, you'll see I now declare activities = []; Then, I assign data to it.

I believe there's a few ways mentioned in Caspar's and CyberJus' posts that would work, now that I got the HTML working.


    <template>
      <lightning-card title="Activities" icon-name="custom:custom14">
        <ul class="slds-m-around_medium">
          <template for:each={activities} for:item="ac">
            <span key={ac.id}>
              <div class="slds-col">
                   <lightning-input type="checkbox" label={ac.Title__c} ></lightning-input>
              </div>
            </span>
          </template>
        </ul>
      </lightning-card>
    </template>

import {LightningElement, wire} from 'lwc';
import getAllEventActivities from '@salesforce/apex/EventActivities_Ctrl.getAllEventActivities';

export default class EventActivityChecklist extends LightningElement {
  
  activities = [];
  @wire(getAllEventActivities) getAllEventActivitiesHandler({ data, error }) {
    if (data) {
      this.activities = data;
      console.log(data);
    } else if (error) {
      console.log(error);
    }
  }
}

public with sharing class EventActivities_Ctrl {

    @AuraEnabled (cacheable=true)
    public static List<Event_Activity__c> getAllEventActivities() {
      return [SELECT id, Title__c, Type__c 
              FROM Event_Activity__c 
              ORDER BY Type__c ASC];
    }
}

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.