[SalesForce] How to Filter a Lightning Component based on data elsewhere on the page

Short version: How do I filter the data in a custom Lightning Component based on data in another Component and/or elsewhere on the Page?

I'm creating a Customer Service Community. I want to show users records in a Custom Object that are grouped by Topic. I want to show these records on the native Topic Detail page, filtered by the Topic that is available on the Topic Detail page – which the user selects by clicking on a Featured Topic tile.

I was disappointed to find that Salesforce hasn't yet created a Lightning Component that does this – something which can already be done in the Classic environment. So I decided to teach myself how to make Lightning Components.

So far:

  • I have created a component that can display custom object records of a particular Topic, when I select the Topic in the SOQL query using a WHERE clause.
  • I have also figured out how to pick a Topic value using a Design Attribute.
  • But I have no idea how to reference the Topic that is available elsewhere on the Topic Detail page. Both the Headline native component and the Search Results native component filter by Topic name. I don't know how, though.

Here is my SOQL, which currently returns records from Materials__c for Topic = 'TOPIC1'.

    Set<Id> entityIds = new Set<Id>();
    for(TopicAssignment ta: [SELECT Id, TopicId, EntityId FROM TopicAssignment WHERE Topic.Name = 'TOPIC1'])
    {
    entityIds.add(ta.EntityId);
    }
        System.debug('entityIds :' + entityIds);
    List<Materials__c> cntLst = [SELECT Id, Name FROM Materials__c WHERE Id IN :entityIds];
        System.debug('cntLst :' + cntLst); // This will hold the Contact Records comes under the topic 'Test1'

SO: How do I change the WHERE clause dynamically to match the Topic shown on the page where I place my component?

[EDIT: Here are the various parts of my component, which are cobbled together from various sources, and not all of which I understand]

APEX CLASS:

    public class MaterialTopicController {
    @AuraEnabled
    public static list <Materials__c> fetchContact(String 
    selectedSubjectJavascript) {
    Set<Id> entityIds = new Set<Id>();
    for(TopicAssignment ta: [SELECT Id, TopicId, EntityId FROM TopicAssignment WHERE Topic.Name = :selectedSubjectJavascript])
    {
        entityIds.add(ta.EntityId);
    }
    List<Materials__c> cntLst = [SELECT Id, Name FROM Materials__c WHERE Id IN :entityIds];
    return cntLst;
    }
    }

LIGHTNING COMPONENT:

    <aura:component controller="MaterialTopicController" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
    <aura:attribute name="TopicSearch" type="String" access="global" />
    <aura:attribute name="TopicSearchDesign" type="String" access="global" />
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:attribute name="ListOfTopicContact6" type="Materials__c[]" description="store materials related to a specific topic"/>
    <ul>
    <aura:iteration items="{!v.ListOfTopicContact6}" var="con6">
      <li type="dice">Topic Contact : {!con6.Name}</li>
    </aura:iteration>
    </ul>
    </aura:component>

JAVASCRIPT:

    ({
    doInit: function(component, event, helper) 
    {

    var selectedSubject = component.get("v.TopicSearch");

    //call apex class method
   var action = component.get('c.fetchContact');
   action.setParams({
        "selectedSubjectJavascript": selectedSubject
    });
   action.setCallback(this, function(response) 
   {
   //store state of response
   var state = response.getState();
   if (state === "SUCCESS") 
   {
   //set response value in ListOfTopicContact6 attribute on component.
   component.set('v.ListOfTopicContact6', response.getReturnValue());
   }
   });
   $A.enqueueAction(action);
   },
   })

Best Answer

If you want to reference the currently selected topic, and load a component on the topic detail page you can do so by fetching the topic name and/or Id from the url in your client side controller (easiest approach).

Another approach, as mentioned in the comments, is by passing the topic through an event.