foreachrecordballerinaballerina-swan-lake

How can I iterate over nested and optional record arrays in Ballerina?


In my Ballerina program I have the below nested record structure and, I want to iterate through the profiles array within associatedProfiles of an Allotment record.

Here's a simplified version of my code:

type Allotment record {
    string inventoryBlockName?;
    AssociatedProfiles associatedProfiles?;
};

type AssociatedProfiles record {
    Profile[] profiles?;
};

type Profile record {
    string creatorCode?;
};

I tried using a foreach loop as shown below, but the compiler is raising issues.

foreach Profile profile in allotment.associatedProfiles?.profiles? {
    // Code logic here
}

So what is the recommended approach to iterate over optional nested records in Ballerina?


Solution

  • In this scenario, it is recommended to assign the allotment.associatedProfiles?.profiles to a variable and perform an is check to eliminate the possibility of having nil values. This helps narrow-down the variable type to Profile[].

    Profile[]? profiles = allotment?.associatedProfiles?.profiles;
    
    if profiles is () {
        // Handle `profiles` being `()` due to `AssociatedProfiles` or `Profile` being `()`
    } else {
        // `profiles` is `Profile[]`
        foreach Profile profile in profiles {
            io:println(profile.creatorCode);
        }
    }
    

    And if you choose to return or continue within the if block, the else block is not required, as the type will be narrowed after the if block anyway.

    Profile[]? profiles = allotment?.associatedProfiles?.profiles;
    
    if profiles is () {
        // Handle `profiles` being `()` and return.
        return;
    }
    
    // `profiles` is `Profile[]` here.
    foreach Profile profile in profiles {
        io:println(profile.creatorCode);
    }