Jump to content

Novice filter() issue…


celfred
 Share

Recommended Posts

Hello,

I can't understand how this destructive filter() work.

Here's my code (with annotations to explain my issue) :

  $teamPlayers = $pages->find("parent.name=players, team=$team");
  bd($monster->name.':'.$teamPlayers->count()); // There should be 24 players in my team (which is the case on first call)
  foreach ($teamPlayers as $p) {
    $result = $p->child("name=tmp")->tmpMonstersActivity->get("monster=$monster, bestTime>0");
    if ($result) {
      $p->bestTime = $result->bestTime;
    } else {
      $p->bestTime = 0;
    }
  }
  $teamPlayers->filter("bestTime>0")->sort("bestTime"); // I want to return only the list of players having a best time on this monster
  return $teamPlayers;

 

My problem is that after several calls (for all monsters) the number of players in the team is not 24 but 1… I guess the $teamPlayers never resets and I can't understand why line 1 doesn't start with 24 again…

If I code this for the 2 last lines, it works :

  $teamMates = $teamPlayers->find("bestTime>0")->sort("bestTime");
  return $teamMates;

But I would like to understand what's going on with my 1st version (I guess it is the destructive aspect of filter()) ?

So if someone could take a little time to explain, I would appreciate ?

Link to comment
Share on other sites

  • 2 weeks later...

sorry too big fingers... let's resume ?

there you assign a value to $teamPlayers

when afterwards you apply a method to this var, well, you apply a method but don't store the result of this method in a var which is exactly what you eventually do with your

$teamMates = $teamPlayers->find("bestTime>0")->sort("bestTime");
return $teamMates;

there you apply a method on $teamPlayers and store the result in $teamMates ?

hope it helps

have a nice day

  • Thanks 1
Link to comment
Share on other sites

  • 3 weeks later...

Hello @virtualgadjo

Thanks a lot for your answer. I thought I subscribed to the thread but it didn't work so I am seeing this answer just now. Sorry…

I understand your point and tried to look at my issue again. If I got it well, I tested :

$teamPlayers = $teamPlayers->filter("bestTime>0")->sort("bestTime");

and this should work the same as what I did with teh $teamMates var, but…

It doesn't because my $teamPlayers var seems to be gradually destroyed by the filter() method. And that is exactly what I don't understand : why doesn't it come back to 24 when I repeat line 1 :

  On 9/29/2021 at 8:54 AM, celfred said:
$teamPlayers = $pages->find("parent.name=players, team=$team");
Expand  

To try and be exhaustive in my explanations, My structure is like this :

  • in my template, I have a foreach($allMonsters as $m) listing all 'monsters'
  • for a particular monster ($m), I call the method getPosPlayer() trying to get the position of a player according to his or her best time
  • In the getPosPlayer() method, I call getAllTeamTimes() method in which there is the code I mentioned in my first post (hence the part responsible for finding all team players (which doesn't return 24 after a few loops using filter()…which seems to degrade $teamPlayers var although on line 1 of that method I initialize it - or at least I wish I could initialize it ?)

Anyway, if I don't use filter() it works, but I wish I could understand what's going on…

Thanks again for helping !

Link to comment
Share on other sites

hi,

hard to answer without testing completely but i think the problem stays the same as above, you first define $teamplayer and then apply a foreach to it and then again a filter to it keeping the same var name

honestly, just php thinking, pw or not, what i would do for debug purpose in your case woud be a print_r of $teamplayer just after its first setting, one more after the foreach, nbot sure it would be any difference... and, again, use a new var name for your last call, something like this
 

$teamPlayers = $pages->find("parent.name=players, team=$team");
//first one
print_r($teamPlayers);

  bd($monster->name.':'.$teamPlayers->count()); // There should be 24 players in my team (which is the case on first call)
  foreach ($teamPlayers as $p) {
    $result = $p->child("name=tmp")->tmpMonstersActivity->get("monster=$monster, bestTime>0");
    if ($result) {
      $p->bestTime = $result->bestTime;
    } else {
      $p->bestTime = 0;
    }
  }

//second one, not sure it will different from the first one as you don't seem to replace the value in $teamPlayers
print_r($teamPlayers);
// and here, what seems the most logical way to do it imho would be
$teammates = $teamPlayers->filter("bestTime>0")->sort("bestTime"); // I want to return only the list of players having a best time on this monster
return $teammates;
// a print_r($teammates); would also be a good way to see if anything happens

but honestly, without kowing exactly the page structure, i just try to guess what those $p->child are... and i must say, usually when using a foreach i first set an empty var and feed it with the first array elements including those i've modified
afterwards you can play with ne new array knowing you haven't modified the base one

hope it helps in terms of debugging path ?

have a nice day

Link to comment
Share on other sites

Thanks again for the explanations which is somehow what I do for debugging. I 'follow' my var using bd() and that's what surprises me when I use filter() as explained mentionned above : first loop : $teamPlayers->count() is 24 filter() reduces it to 3 $teamMates, 2nd loop, $teamPlayers initializes back to 24 (as expected) and filter() reduces $teamMates to 3, 3rd loop, $teamPlayers initialize at 3 (???). And after a couple of other loops, when filter() reduces $teamMates to 1, $teamPlayers stays at 1…

And I can't explain this 'destructive' mode that never comes back to the initial value.

The 'child' thing is just the page where I save the bestTime field for a player.

Anyway, I think you've spent enough time trying to help me and I, again, thank you very much for this. I guess I'll have to further dig this filter() method (which I thought I eventually grasped since I use it somewhere else in my code ;)). Maybe things will get better as my skills improve with time.

 

Link to comment
Share on other sites

Hi again ?

wow, funny behavior you describe here!!!

in this kind of situation, first thing i would check is if this $teamPlayers var doesn't appear in another place it should not and where it stores something causing this surprising thing...
of course, be sure not to use any cache as it could be your enemy here ?

hope you'll figure this out

have a nice day

  • Like 1
Link to comment
Share on other sites

Ok. So one thing you've just written triggered an idea and made me closer to understanding the issue ?

I added :

  $pages->unCacheAll();

in my template just before calling my method getPosPlayer() and now the weird behavior I related is back to normal : 24 players initialized all the time and my initial filter() way of doing things worked as expected.

So it is a cache issue ! But I (for the moment) don't know where it comes from. So I'll dig this cache thing and try to find a way to explore what is being cached (and why).

Thanks a lot for your help.

Link to comment
Share on other sites

Hi,

great news! ?

have you looked at your template cache settings (or procache if you use it) some pages containing dynamic content, pagination, forms, and so on are better not to be cached sometimes, depending on what you cache or not

the main thing is now you'll stop loosing your hair ?

and my pleasure

have a nice day (better now :))

Link to comment
Share on other sites

  On 10/24/2021 at 2:05 PM, virtualgadjo said:

have you looked at your template cache settings (or procache if you use it) some pages containing dynamic content, pagination, forms, and so on are better not to be cached sometimes, depending on what you cache or not

Expand  

Well, after some more research, I still don't get it. My page template's cache is set to 'disabled' (I don't use Procache) and I can't find any place where I would set some cache for this part in my code, but when I do $pages->unCacheAll(), it gets rid of about 100 things and then my code works…

So I guess I'll keep losing my hair, but now I know where they go : it's a cache issue ? I'll try to find some resources explaining how that works.

Bye !

Link to comment
Share on other sites

Hello again,

be careful, you may end with a fky rink like me on top of your head ?

being intrigued by your issue, i've had a look at this
https://processwire.com/api/ref/pages/uncache-all/

and it sounds like an explanation that's good to know (i often use pagination without having ran into the same issue as yours... so far)

have a nice day
bye

  • Thanks 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...