2

I am building a navigation component that can be used in communities that will let you specify the navigation set (that you create declaratively).

the problem I am facing is that when trying to filter the NavigationLinkSet records by NetworkId, it is not possible to compute the network Id. This forces the component configurator to list all NavigationLinkSet records (this is not ideal because I just want to list the ones associated to the community in context).

global with sharing class NavigationController extends VisualEditor.DynamicPickList {
 private List<NavigationLinkSet> navigationLinkSets;

    global NavigationController() {
        Id networkId = Network.getNetworkId();
        // networkId is always null
        // the query does not retrieve any record
        /*
         this.navigationLinkSets =  [
            SELECT 
                DeveloperName,
                MasterLabel, 
                NetworkId, 
                Network.Name
            FROM NavigationLinkSet
            WHERE NetworkId =: networkId
            ORDER BY MasterLabel
        ]; 
        */
        // retrieves all NavigationLinkSet records (not ideal)
        this.navigationLinkSets =  [
            SELECT 
                DeveloperName,
                MasterLabel, 
                NetworkId, 
                Network.Name
            FROM NavigationLinkSet
            ORDER BY MasterLabel
        ];
    }

    global override VisualEditor.DataRow getDefaultValue() {
        NavigationLinkSet entry = this.navigationLinkSets[0];
        return new VisualEditor.DataRow(
            entry.MasterLabel + ' (' + entry.Network.Name + ')',  // adding the network name to the label, so it is possible to know if record is part of the community
            entry.DeveloperName, 
            true
        );
    }
    
    global override VisualEditor.DynamicPickListRows getValues() {
        Id networkId = Network.getNetworkId();
        VisualEditor.DynamicPickListRows values = new VisualEditor.DynamicPickListRows();

        for (NavigationLinkSet entry : this.navigationLinkSets) {
            values.addRow(new VisualEditor.DataRow(
                entry.MasterLabel + ' (' + entry.Network.Name + ')',  // adding the network name to the label, so it is possible to know if record is part of the community
                entry.DeveloperName
            ));
        }
        
        return values;
    }

}

This is the result (navigation sets from other communities get listed). The expected result would be only options (the ones belonging to demo since this is the community in context).

final outcome

I wonder if someone has found a way to compute the network Id.

Please consider that component I am building is configurable by any user. In order to make it configurable declaratively, I have specified a data source in the component .xml file which is where I cannot compute the network id.

<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <isExposed>true</isExposed>
    <masterLabel>Navigation</masterLabel>
    <targets>
        <target>lightningCommunity__Page</target>
        <target>lightningCommunity__Default</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightningCommunity__Default">
            <property 
                label="Menu Name" 
                name="menuName" 
                type="String"
                datasource="apex://NavigationController" 
            />
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

2 Answers 2

0

You should be able to pass the networkId from your LWC Navigation component to the controller dynamically using e.g.

import communityId from '@salesforce/community/Id';

https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.create_community_info

https://developer.salesforce.com/blogs/2020/07/advanced-community-navigation-components

You can then update your controller to accept networkId as a parameter and use it in your query.

2
  • I should have been clear, I have updated my question, thank you for your answer Aug 16, 2021 at 21:16
  • 2
    Yes I misunderstood the original question. Thanks for the update. Currently I am not sure how solve this to meet your requirements.
    – Jordan
    Aug 16, 2021 at 21:40
0

I don't think you can use Network.getNetworkId() in this context. I believe the builder framework doesn't have access to the Experience Site's ID. The site itself is in an iframe and the properties panel is rendered outside of this. So they may not be connected this way. This is a theory as I can find no documentation on it. So please correct me if someone finds a source.

There is a solution but it makes the component code specific to one Experience Site. It's a little fragile, but it works if you really want to make sure you're only showing the navigation for one experience site.

global class NavigationController extends VisualEditor.DynamicPickList {
    global Id getNetworkId() {
        Network site = [
                SELECT Name, Id
                FROM Network
                WHERE Name = 'my-experience-site' LIMIT 1
        ];
        return site.Id;
    }

    global override VisualEditor.DataRow getDefaultValue() {
        VisualEditor.DataRow defaultValue = new VisualEditor.DataRow('Default Navigation','Default Navigation');
        return defaultValue;
    }

    global override VisualEditor.DynamicPickListRows getValues() {
        Id networkId = getNetworkId();
        VisualEditor.DynamicPickListRows picklistValues = new VisualEditor.DynamicPickListRows();
        List<NavigationLinkSet> navigationLinkSetList = [
            SELECT MasterLabel, DeveloperName
            FROM NavigationLinkSet
            WHERE NetworkId = :networkId
        ];

        for (NavigationLinkSet navigationLinkSet : navigationLinkSetList) {
            VisualEditor.DataRow value = new VisualEditor.DataRow(navigationLinkSet.MasterLabel,navigationLinkSet.DeveloperName);
            picklistValues.addRow(value);
        }
        return picklistValues;
    }
}

In the getNetworkId method, the string my-experience-site is the name of your Experience Site. I might store this in a Custom Setting. Some cons to this approach:

  • If you change the name of your Experience Site, this would break.
  • This makes your component specific to one Experience Site.

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.