cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
Highlighted
jernejp
Level: Powered On

Nested Loops and API calls

Hi,

 

I'm building an application to add employee activities to our ERP, and then assign attendees to those activities.

First I have to make a call to our ERP to add an activity, which then returns the Activity ID from ERP. Then using that, I'm supposed to add all of the attendees to the activity.

Theres multiple activities that can have multiple attendees.

During the process, I'm saving all of the Activities to a table in my database, and Attendees to another table (and they're connected by activity_id field in Attendees table.

 

Then I make a call to get AllActivities into a collection to loop through.

 

This is what I currently have:

 

ForAll(
    AllActivities;
    Collect(
        AddedActivity;
        'My API'.AddActivitiesToBusinessPartner(
            {
/* API CALL HERE */ } ) ) )

 

 

My database schema is as follows, and below is the collection that gets created:

 

 

dbschema.PNG

added1.PNGadded2.PNG

 

What I can't figure out is: how would I go about nesting another ForAll loop in there, that would make the other API call to add attendees to the activity?

So basically:

  1. add activity
  2. get ID from the ERP
  3. loop trough database and see if there's attendees
  4. add attendees to ERP

 

1 ACCEPTED SOLUTION

Accepted Solutions
Community Support Team
Community Support Team

Re: Nested Loops and API calls

Hi @jernejp ,

Yeah, you are right. I have made a test on my side, please consider take a try with the following formula:

ForAll(                   /* <-- Seperated ForAll Loop */
    AllActivities;
    Collect(
        AddedActivity;
        {
ActivityID: AllActivities[@id], /* <-- add a column to store the id value from the AllActivities */
ResponseRecord: 'MyApi'.AddActivitiesToBusinessPartner( { ... } )
} ) );; ForAll( /* <-- Nested ForAll Loop */ AddedActivity; ForAll( Filter( '[dbo].[attendees]'; activity_id = AddedActivity[@ActivityID] ); 'MyApi'.AddAttendantsToAnExistingActivity( { .... } ) ) )

Please consider take a try with above formula, check if it could help in your scenario.

 

Best regards,

Community Support Team _ Kris Dai
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.
13 REPLIES 13
jhall
Level 8

Re: Nested Loops and API calls

Off the top of my head, I'd have to say that this is the kind of thing that I bring in Flow for.  My second thought would be I'd probably build toward distinct ForAll() functions just because "Looping" isn't exactly PowerApps strong suit. 

But if I have some time today to get back to this I'll take a look to see if I spot something.

jernejp
Level: Powered On

Re: Nested Loops and API calls

Hm, I have some problems with Flow, because it keeps returning True instead of actual results...

This is the code I've gotten together so far, but I think only the first API calls are executing, not the second:

 

ForAll(
    AllActivities;
    Collect(
        AddedActivity;
        'MyApi'.AddActivitiesToBusinessPartner(
            {
	    }
        )
    );;
    ForAll(
        Filter(
            '[dbo].[attendees]';
            activity_id = AllActivities[@id]
        );
        'MyApi'.AddAttendantsToAnExistingActivity(
            {

            }
        )
    )
)

And thanks @jhall !

jhall
Level 8

Re: Nested Loops and API calls

Yeah, I don't think that's doing what you think it is.  Take a look a the ForAll() documentation.  PowerApps absolutely doesn't do "Loops" like those of use are familiar with from other programming languages.  In fact, the closest you really come to doing loops like this wind up using Timers.  You can fire off timers that run a series of commands and then the last thing can be to fire off another Timer (or the same one).

However, just because you can do a thing...

jernejp
Level: Powered On

Re: Nested Loops and API calls

Hm, so I can't do loop-within-a-loop. Any other ideas how I might solve this? I've resorted to this:

ForAll(
    ResponseFromInfor;
    UpdateIf(
        '[dbo].[activity]';
        additional_costs = COSTS;
        {erp_id: Value(ACTIVITY)}
    )
)

Meaning that I've added a column in the activity table, and then I wanted to loop trough response and find which activities in the ERP correlate with those in my database. Then I would run a seperate loop to send data to ERP.

However the above code acts weird - it works for way too long, and the ACTIVITY number that it uses are right at first (for example 4000061), but then they start to increment and I have no idea why that happens.

Super User
Super User

Re: Nested Loops and API calls

You can have a ForAll inside a ForAll.

For example, I have a Parent table (SampleList) and a child table (SampleListSubList) where the ID from the parent table joins to the ParentID in the child table. The code below executes as expected (the two collections are populated).

You need to be careful of the column names. For example, both the Parent and Child table have an ID column, so I use RenameColumns to disambiguate (I change ID in the child table to childID). I suspect your issue relates to disambiguation and suggest you use RenameColumns to remove any confusion.

Clear(colParent);
Clear(colChild);
ForAll(
    FirstN(
        '[dbo].[SampleList]',
        5
    ),
    Collect(
        colParent,
        ID
    );
    ForAll(
        Filter(
            RenameColumns(
                '[dbo].[SampleListSubList]',
                "ID",
                "childID"
            ),
            ParentID = ID
        ),
        Collect(
            colChild,
            {
                ParentID: ID,
                ChildID: childID
            }
        )
    )
)
Community Support Team
Community Support Team

Re: Nested Loops and API calls

Hi @jernejp ,

Based on the issue that you mentioned, I think you have some misunderstadning with the ForAll function (or Loop iterator) in PowerApps.

 

Based on the nested ForAll formula that you provided above, I could not find ant syntax error with it. I think the second API Call within your nested ForAll formula would be executed successfully.

When you execute the nested ForAll formula within your app, is there some error message or issue occured?

 

For your second ForAll formula, when the ForAll function is executed, each loop process would retrieve the ACTIVITY value from the ResponseFromInfor data source (retrieve one record sequentially from your ResponseFromInfor  in each loop process). If the ACTIVITY values within the ResponseFromInfor data source is not same with each other, the retrieved ACTIVITY value within each loop process would also be different.

Note: The nested ForAll loop is supported within PowerApps.

 

More details about the ForAll function in PowerApps, please check the following article:

ForAll function

 

More details about the nested ForAll formula within PowerApps, please check my response within the following thread:

https://powerusers.microsoft.com/t5/General-Discussion/Nested-ForAll-column-identificiation/m-p/2768...

 

 

Best regards,

Community Support Team _ Kris Dai
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.
jernejp
Level: Powered On

Re: Nested Loops and API calls

ForAll(
    AllActivities;
    Collect(
        AddedActivity;
        'MyAPI'.AddActivitiesToBusinessPartner(
            {
            }
        ).dll
    );;
    ForAll(
        AddedActivity;
        Collect(
            tempCollection;
            AddedActivity.ACTIVITY
        )
    )
);;

This is the code that I have now updated, and the second loop is executed. I wanted to see if the code is working, so I'm collecting the data into a tempCollection, but I'll replace that part later with the actual API call.
However, I'm getting duplicated values:

added3.PNG

Any more suggestions? Thank you so far for helping me out!

Community Support Team
Community Support Team

Re: Nested Loops and API calls

Hi @jernejp ,

Based on the formula you provided, I think there is something wrong with it.

 

When your 'MyAPI'.AddActivitiesToBusinessPartner() formula executes for the first time, the AddedActivity collection would be populated with appropriate value (one record). Then your nested ForAll() formula executed based on the AddedActivity collection, then the tempCollection collection would be populated with proper value (one record).

But when your 'MyAPI'.AddActivitiesToBusinessPartner() formula executes for the second time, the new value is added into your AddedActivity collection (two records), then your nested ForAll() formula executed based on the modified AddedActivity collection, the previous loop added record in your AddedActivity collection would also be added again into your tempCollection collection, so the duplicated records would show up in your tempCollection collection.

 

Based on the issue that you mentioned, I think the nested ForAll functionality could not achieve your needs. Please consider modify your formula as below:

 

/* Execute your two ForAll formulas separately */
ForAll( AllActivities; Collect( AddedActivity; 'MyAPI'.AddActivitiesToBusinessPartner( { } ).dll ) );; ForAll( AddedActivity, Collect( tempCollection; AddedActivity.ACTIVITY ) )

 

Please consider take a try with above solution, then check if the issue is solved.

 

Best regards,

 

Community Support Team _ Kris Dai
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.
jernejp
Level: Powered On

Re: Nested Loops and API calls

I appreciate the time and effort you're all putting into helping me out.

While I tried to find a solution, I'm afraid I over-complicated things.

 

So this code would be closer to what I'm trying to achieve. Within the second loop, I need to access AllActivities collection, because it contains activity_id that I need to get the attendees from the database. 

 

ForAll(
    AllActivities;
    Collect(
        AddedActivity;
        'MyApi'.AddActivitiesToBusinessPartner(
            {
	    }
        )
    );;
    ForAll(
        Filter(
            '[dbo].[attendees]';
            activity_id = AllActivities[@id]
        );
        'MyApi'.AddAttendantsToAnExistingActivity(
            {

            }
        )
    )
)

I'm starting to think if I actually need a triple nested loop?

So first to go through activities and add them, get a response from ERP to know the activity, and then loop trough all attendees that attended the activity and add them?

Helpful resources

Announcements
firstImage

Watch Sessions On Demand!

Continue your learning in our online communities.

SecondImage

Follow PowerApps on Twitter

Stay Up-to-Date by following PowerApps on Twitter

Top Community Contributors for July 2019

Top Community Contributors for July 2019

Let's thank our top community contributors

Power Platform 2019 release wave 2 plan

Power Platform 2019 release wave 2 plan

Features releasing from October 2019 through March 2020

FirstImage

Power Platform World Tour

Coming to a city near you

thirdimage

PowerApps Community User Group Member Badge

Fill out a quick form to claim your user group badge now!

FourthImage

Join PowerApps User Group!!

Connect, share, and learn with your peers year-round

FifthImage

Dynamics 365 and Power Platform April 2019 Release notes

Features releasing from April 2019 through September 2019!

Users Online
Currently online: 85 members 3,896 guests
Please welcome our newest community members: