ForEach Vs ApplyComponents

Certified Lead Developer

I have created a editable grid by using two rules, one rule for grid configuration and second to create "gridRowLayout". When second rule is being iterated in foreach then on save of each field of grid entire form is refreshing itself which is not happening when second rule is being iterated by  applycomponents. Here something, I am missing or someone else also faced same?

  Discussion posts and replies are publicly visible

  • 0
    Certified Lead Developer

    applyComponents might as well be deprecated.  You can achieve the same functionality with a!forEach, except that it's a little simpler, more readable, and occasionally it's even possible to do stuff that was impossible with applyComponents.  And you don't have to learn partial evaluation to be able to do it.

    It's so might as well be deprecated, that when they invented a!forEach they actually removed the recipes using a!applyComponents from the documentation.  Go ahead and replace it with a!forEach that does the same thing, or the same thing only better.

    Future developers on the project, maybe even future you, will thank you.

  • a!forEach() is definitely the way to go, for all the reasons David mentions.

  • 0
    Certified Lead Developer
    in reply to Dave Lewis

    Thanks David for the answer. I might have not been able to explain the point here clearly. I agree that I can achieve same thing with a!forEach instead of a!applyComponents without partial evaluation. But here, my point is when we use a!ForEach in same code then grid is refreshing itself on each save of grid field where as in a!applyComponents it is not refreshing, which makes the performance of grid better. 

  • 0
    Certified Lead Developer
    in reply to HarshKumarAgarwal

    I doubt that the applyComponents vs forEach is what is causing that difference in behavior, and suspect it is something regarding how the code is utilizing the saveInto parameter or querying the data between the two approaches.  If you could post your code, happy to take a look!

  • 0
    Certified Lead Developer
    in reply to Evan Rust

    Hi Evan, let's give it a try.

    I have created one inner rule name as HARSH_Test with two inputs: data (Any Type) and index (Number Integer). Code for inner rule is as follows:

    a!gridRowLayout(
    id: ri!index,
    contents: {
    a!textField(
    value: ri!data[ri!index].id,
    saveInto: ri!data[ri!index].id
    ),
    a!textField(
    value: ri!data[ri!index].code,
    saveInto: ri!data[ri!index].code
    ),
    a!textField(
    value: ri!data[ri!index].name,
    saveInto: ri!data[ri!index].name
    ),
    a!textField(
    value: ri!data[ri!index].description,
    saveInto: ri!data[ri!index].description
    )
    }
    )

    Now called this inner rule from another main rule and code for that is as follows:

    a!localVariables(
    local!data: {
    {id:null,code:"",name:"",description:""},
    {id:null,code:"",name:"",description:""},
    {id:null,code:"",name:"",description:""},
    {id:null,code:"",name:"",description:""}
    },
    a!gridLayout(
    label: "Looping Test",
    headerCells: {
    a!gridLayoutHeaderCell(label: "Id"),
    a!gridLayoutHeaderCell(label: "Code"),
    a!gridLayoutHeaderCell(label: "Name"),
    a!gridLayoutHeaderCell(label: "Description")
    },
    rows:
    a!forEach(
    items:local!data,
    expression:rule!HARSH_Test(
    data: local!data,
    index: fv!index
    )
    )
    /*a!applyComponents(
    function: rule!HARSH_Test(
    data: local!data,
    index: _
    ),
    array: 1 + enumerate(
    count(
    local!data
    )
    )
    )*/
    )
    )

    Here I have pasted code with a!forEach as well as a!applyComponents. Just comment out one while using other.

    Now when we have an editable grid present then try to save in a row for all columns one by one (bit faster). You will observe the code with a!forEach will refresh and make you wait for focusing on next column which is not the case with a!applyComponents.

    Here, I am not saying that a!applyComponents is better or not as I know with a!forEach we can do more stuff but this one use case which I found better in terms of performance. Please revert if I am missing something in code. 

  • a!forEach() is the ultimate looping function that fits to any situation.

  • 0
    Certified Lead Developer
    in reply to arunramanathtm

    I have been using a!forEach only since it comes in SAIL and continue using that instead of apply or applyComponents. The reason, I put this post here to get a discussion with logic that what is not correct with a!forEach loop. Whereas applyComponents being a older function and a!forEach is a replacement of that but still performing better in specific scenario and in future it is going to upgrade?

  • 0
    Certified Lead Developer
    in reply to HarshKumarAgarwal
    But here, my point is when we use a!ForEach in same code then grid is refreshing itself on each save of grid field where as in a!applyComponents it is not refreshing

    What evidence are you basing this on, BTW?  From what I can tell from the code you posted before for to look at, I would not be necessarily expecting any "auto refresh" behavior on your grid, in either configuration, and I'm unclear on what you'd even be seeing to suggest as much.

  • 0
    Certified Lead Developer
    in reply to HarshKumarAgarwal

    Thanks everyone for the replies. I got the problem here. when I use ri!data[ri!index].id inside foreach loop instead of fv!item.id then it refreshes the grid on save of each cell. Following is the right syntax: 
    a!forEachfv!item.id
    a!applyComponents: ri!data[ri!index].id