Unable to iterate using for each after 50 records in entity

Unable to iterate using for each after 50 records in entity

  

Hi,

I am trying to create an entity by importing an excel consisting of 80records.
The entity is created successfully and I can view the data in the entity with all 80 records. However, when I use for each to iterate individual record, it picks only the first 50 records and exits the loop


Can you please guide me on this? Does free version has a limit of 50 records per entity?





Is that Aggregate being displayed in a records list or table list on the page?

I believe OS will actually only fetch the number of records that the widget is set to display, so that it doesn't pull unneeded resources. 

Could you give an example of where you are now trying to iterate?

Hi Jordan.


We are not displaying the entire aggregate. Here is the scenario:

1. User keys-in his Employee ID and clicks on SUBMIT

2. In Submit action, I have a for each widget with Record List as the aggregate's list (GetMyProfileDetails.List).

3. Then a simple "if" to check if the entered employee ID exists in the entire 80 records, when TRUE the "GetMyProfileDetails.List.Current" will be saved to a local variable of same(MyProfileDetails) datatype.


Whats wrong/not working is, it doesnot iterate after the 50th row.



Hi Tauseef,

You can try to set the start index and max. iterations. The start index should be set to 0, and the maximum iterations should be set to the count of the aggregate (not the length, which is the amount of records returned by the query).


Sam.

Solution

Yes try specifying the start and end for the For Each, though it should default to those automatically in my experience.


However, for your Use Case I also recommend using the ListIndexOf System action.  It will return -1 if the item doesn't exist, or the Index of that item if it does exist.

You would then assign this value by GetMyProfileDetails.List[ListIndexOf.Position].MyProfileDetails (or whatever your entity name is)

You do not need to iterate through the list yourself to find a specific item.

Solution

Hi Sam,


Providing Start Index and Max. Iterations did not make any difference in the length of Record List being fetched. It still fetched top 50 records. Nor using the Count attribute helped. I worked through the solution provided by Jordan. Will share the details soon.


Sam Rijkers wrote:

Hi Tauseef,

You can try to set the start index and max. iterations. The start index should be set to 0, and the maximum iterations should be set to the count of the aggregate (not the length, which is the amount of records returned by the query).


Sam.



Hello Tauseef,

1. If the aggregate is connected to a TableRecords / ListRecords in the screen, it will retrieve ONLY the number of lines specified in the screen table through the Line Count property.

So, no matter what you do if for each, if the Line Count has 50, there are only 50 records in the aggregate list.

2. Using a preparation's aggregate in a screen action is really bad practice. It will have a huge negative impact in your application.

Instead, create a new aggregate in the screen action and use it instead. It will not cause negative impact and you will be able to iterate all records you want.

3. If you want to work with one record from the table, every time the user clicks a line, it becomes the TableRecords.List.Current. Use it.

Cheers

I want to put some nuances to Eduardo's 2nd point. The reason why performance can be impacted is that if you use an Aggregate from the Preperation in a Screen Action, the Aggregate results are put in the View State, which may slow down a page considerably. However, how "huge" it is depends on the amount of data, and 50 or 80 records aren't all that much (performance starts degrading with much larger amounts of data). Regardless, the advice you'll also find in the online training material, is not to create a new Aggregate, but to use the Refresh Data Statement:

After the Refresh Data you can use the Aggregate's data without a performance penalty caused by a large View State.

Hi Kilian.

About the "huge", I agree. It depends on the amount of data.

About the refresh data type, it depends, if you want to refresh the data in the screen or if you want to process information of a line (or more lines). In the first case, yes. In the second, using the current of the table list or even the list is always more appropriate than messing with the preparation aggregate, or if you need to deal with more records than those are being shown, bring the data again from the database is the best option.

In the case in question, the best option is to use an aggregate to fetch data again, filtered by the id, to check if it is there, and proceed accordingly.

Cheers

Hi Jordan,


I made use of the ListIndexOf and was able to iterate through the list and fetch the required details.
However, this doesn't work when placed in Client Action, so had to move this a server action and it worked perfectly. (Might be helpful for others if they are trying to execute it form Client action by mistake).


@Eduardo, 

Thanks for the detailed pointers. The second point was really helpful.


Jordan Welch wrote:

Yes try specifying the start and end for the For Each, though it should default to those automatically in my experience.


However, for your Use Case I also recommend using the ListIndexOf System action.  It will return -1 if the item doesn't exist, or the Index of that item if it does exist.

You would then assign this value by GetMyProfileDetails.List[ListIndexOf.Position].MyProfileDetails (or whatever your entity name is)

You do not need to iterate through the list yourself to find a specific item.



Hi Tauseef,

I'm not sure, without seeing actual code, what you did, but I can't think of any situation where you have no errors but inside a Client Action it doesn't work, but it does work in a Server Action. So I don't think it's very "helpful to others" to propose something without knowing why it worked.