3

With the Winter'18 new Lightning Base components I tried to create a lightning:progressIndicator with lightning:progressStep dynamically using an aura:iteration:

<aura:component>
    <aura:attribute name="path" type="CustomPath" />

    <lightning:progressIndicator type="path">
        <aura:iteration items="{!v.path.steps}" var="step">
            <lightning:progressStep label="{!step.label}" value="{!stage.id}"/>
        </aura:iteration>
    </lightning:progressIndicator>
</aura:component>

with all the path info defined in an Apex object and passed into the component:

public class CustomPath {

    @AuraEnabled
    public List<Step> step { get; private set; }    
    ...
}

public class Step {
    @AuraEnabled
    public Id id { get; private set; }

    @AuraEnabled
    public String label { get; private set; }
    ...
}

The page throws strange errors like:

Uncaught Action failed: aura:iteration$controller$itemsChange [Cannot read property 'hasOwnProperty' of undefined]

enter image description here

3
  • How are you passing the stages array? Is this a nested component? Commented Oct 19, 2017 at 22:38
  • I am passing in a Custom Apex object. I updated the question code. Commented Oct 20, 2017 at 10:00
  • We may need this feature which is not yet available as of Spring '18.
    – Thamilhan
    Commented Mar 13, 2018 at 18:36

2 Answers 2

5

I've been playing around and it seems that its a bit buggy.
From my point of view, it doesn't like to get the body rendered dynamically while updating the currentStep.
The following code is a work-around that works, in case no-one else give another idea...

Component

<aura:attribute name="stage" type="Map" default="{id:'id2', label:'Label 2'}" />
<aura:attribute name="progressIndicator" type="Aura.Component" />
<aura:handler name="init" action="{!c.doInit}" value="{!this}" />
<br/><br/><br/><br/>

{!v.progressIndicator}

<ui:button press="{!c.doChangeStage}" label="Button"/>

Controller

({
    doInit : function(component, event, helper) {
        // assume this is what you get from the server call
        var stepsData = [
            {id:'id1',label:'Label 1'},
            {id:'id2',label:'Label 2'},
            {id:'id3',label:'Label 3'},
            {id:'id4',label:'Label 4'}];

        // List of components to create, starting with the father itself
        var stepsPreComponents = [[
            "lightning:progressIndicator",
            {
                "currentStep" : component.getReference('v.stage.id')
            }
        ]];

        // Add the steps
        for (var index in stepsData) {
            var step = stepsData[index];
            stepsPreComponents.push([
                "lightning:progressStep",
                {
                    "label":step.label,
                    "value":step.id
                }
            ]);
        }

        $A.createComponents(
            stepsPreComponents,
            function(components, status, errorMessage){
                if (status === "SUCCESS") {
                    // Remove the father
                    var progressIndicator = components.shift();
                    // Add the rest to the father
                    progressIndicator.set('v.body',components);
                    // Assign it to the view Attribute
                    component.set('v.progressIndicator',progressIndicator);
                } else {
                    alert('Error');
                }
            }
        );
    }, 

    doChangeStage : function(component, event, helper) {
        component.set('v.stage.id', 'id4');
    }
})
2
  • This solution is not nice, but works, I would be glad to have a better solution if anyone finds one... Commented Dec 27, 2017 at 17:07
  • This can be a work around. But still we may need this feature which is not yet available as of Spring '18.
    – Thamilhan
    Commented Mar 13, 2018 at 18:36
0

It looks like either your sample code is incomplete, or you are missing some variables - the main issue seems to be path.currentStep isn't definied in your apex class.

<aura:component>
<aura:attribute name="path" type="CustomPath" />

// There isn't anything in your controller that maps to v.path.currentStep. 
// When the component tries to parse it, it can't read the 'Id' because there is not variable called 'currentSetup', so it results in a 'hasOwnProperty' error
<lightning:progressIndicator currentStep="{!v.path.currentStep.id}"> 
    <aura:iteration items="{!v.path.steps}" var="step">
        <lightning:progressStep label="{!step.label}" value="{!stage.id}"/>
    </aura:iteration>
</lightning:progressIndicator>

To verify that this is correct, try temporarily removing the currentStep attribute on the lightning:progressIndicator and see if it then loads successfully

1
  • Seems to not be connected to current step. I removed it and nothing changed Commented Oct 22, 2017 at 18:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .