cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
akg1421
Helper III
Helper III

Error when Filtering data source before Creating a Collection

Using mydatasource to create mycollection1 before filtering mydatasource to return only specific rows

ClearCollect(mycollection1,Blank());
ForAll(mydatasource As mydatasource,
	Filter(mydatasource,mydatasource.UserId="Jonathan"),
    Collect(mycollection1,
        {
            FullNameOriginator: LookUp(mycollection2, ID = mydatasource.'User (Originator)','Person name'),
            Status:mydatasource.Status,
            'User (Originator)':mydatasource.'User (Originator)',
            Subject:mydatasource.Subject,
            'Work item instructions':mydatasource.'Work item instructions',
            WorkflowWorkItemClaimed:mydatasource.WorkflowWorkItemClaimed,
            'User (UserId)':mydatasource.'User (UserId)',
            'Due date time':mydatasource.'Due date time'
        }
    )
);

I want to create collection based only on filtered rows returned from my datasource. In above query I am trying to filter but it returns error.

 

Is the syntax correct?

11 REPLIES 11

Well, it still navigates to the MainScreen, I had a Timer control before which I disabled and implemented new one with number 0. Now the temp screen just navigates to MainScreen after few seconds. It also starts showing following error, even though it eventually succeeds in loading the data (shows in gallery on mainscreen)

 

"The requested operation is invalid. Server Response: mydatasource failed: An error has occurred. Object reference not set to an instance of an object. clientRequestId: b5c1bef3-ed1e-47de-b838-da84ff76e833"

 

I have two variables calculating in TmpScreen.OnVisible 

 

Set(currUserId,First(Split(User().Email,"@")).Result);
Set(workitemCount,CountRows(Filter(mydatasource, 'User (UserId)'=currUserId)));

//then the collection
ClearCollect(mycollection1,Blank());
ForAll
(
     Filter(mydatasource As mdsPreFilteredRecord,mdsPreFilteredRecord.UserId=currUserId) As mydatasourceRecord
     ,Collect
     (
        mycollection1
        ,{
             FullNameOriginator: LookUp(mycollection2, ID = mydatasourceRecord.'User (Originator)','Person name')
            ,Status:mydatasourceRecord.Status
            ,'User (Originator)':mydatasourceRecord.'User (Originator)'
            ,Subject:mydatasourceRecord.Subject
            ,'Work item instructions':mydatasourceRecord.'Work item instructions'
            ,WorkflowWorkItemClaimed:mydatasourceRecord.WorkflowWorkItemClaimed
            ,'User (UserId)':mydatasourceRecord.'User (UserId)'
            ,'Due date time':mydatasourceRecord.'Due date time'
        }
     )
);

 

 

Just in place of "Jonathan" i'm using the currently logged in user's id via User function in currUserId

Set(currUserId,First(Split(User().Email,"@")).Result);

 

 

 

@akg1421 

 

Do this carefully and revert to the previous working version if it fails, but I recommend the ForAll inside the Collect, not outside.

 

Set(currUserId,First(Split(User().Email,"@")).Result);
Set(workitemCount,CountRows(Filter(mydatasource, 'User (UserId)'=currUserId)));

//then the collection
ClearCollect(mycollection1,Blank());
Collect
(
     mycollection1
     ,ForAll
     (
        Filter(mydatasource As mdsPreFilteredRecord,mdsPreFilteredRecord.UserId=currUserId) As mydatasourceRecord
        ,{
             FullNameOriginator: LookUp(mycollection2, ID = mydatasourceRecord.'User (Originator)','Person name')
            ,Status:mydatasourceRecord.Status
            ,'User (Originator)':mydatasourceRecord.'User (Originator)'
            ,Subject:mydatasourceRecord.Subject
            ,'Work item instructions':mydatasourceRecord.'Work item instructions'
            ,WorkflowWorkItemClaimed:mydatasourceRecord.WorkflowWorkItemClaimed
            ,'User (UserId)':mydatasourceRecord.'User (UserId)'
            ,'Due date time':mydatasourceRecord.'Due date time'
        }
     )
);

 If this doesn't work, just revert to the previous working version with ForAll outside.

 

However, in general, it is better to put ForAll inside and not outside.

The reason is because when ForAll is outside, it is performing the same step inside for each of the individual items.

When it is inside, the outer operation is performed only once.

 

Especially consider the example of a data source and ForAll outside Patch instead of the better way of ForAll inside Patch

 

Especially consider the example of a data source and ForAll outside Patch - in this case,  Patch  is being performed individually for every single item from ForAll. This could be a performance and efficiency problem, and it could significantly reduce the performance of the App if it is used enough times or on large enough data sets.

 

The better way of ForAll inside Patch - here, ForAll from inside returns a Table, that Patch operates on only once on all of the items, so only one call to the data source for all the items at the same time, not one individual call for each of the items individually. In this case, the efficiency and performance may be increased by orders of magnitude depending on the scenario.

 

I wanted you to consider this in case @akg1421 

This example does not Patch - and it may be less important here -  however it would be better to try to get in the habit of using ForAll inside

 

As for your issue with the Timer, do you still have the issue?

 

Helpful resources

Announcements
Power Apps News & Annoucements carousel

Power Apps News & Announcements

Keep up to date with current events and community announcements in the Power Apps community.

Power Apps Community Blog Carousel

Power Apps Community Blog

Check out the latest Community Blog from the community!

Top Solution Authors
Top Kudoed Authors
Users online (6,225)