Call to a member function url() on null in page.changeSlug:after hook

i’d like to update some data in a database when the page slug gets changed.

i’m already doing this when saving the page in the panel with a page model, that works as expected.

i use the following code in my model

$sounds = $this->sounds()->toStructure();
$sound = $sounds->last();
$data['audio'] = Url::path($sound->audio()->toFile()->url());

and i’d like to use nearly the same code on my after changeSlug Hook. With this i always get a “call to a member function url() on null”

'hooks' => [
        'page.changeSlug:after' => function ($newPage, $oldPage) {
            $sounds = $newPage->sounds()->toStructure();
            $sound = $sounds->last();
            $data['audio'] = Url::path($sound->audio()->toFile()->url());
        }
    ],

the only thing i changed is $this to $newPage.

when i remove the ->url() there is no error so toFile() seems to work.

if i compare the data with xdebug both look the same to me

at Save with the Model:
grafik

on Hook
grafik

anyone got a idea how i can solve this? i already tried to do it also in the model on changeSlug but i get the same error like in the hook.

You should not call a member method like url() without checking you have an object first. In fact, you should even check if $sound returns an object, because this will fail if $sounds is an empty collection:

$data = [];
if ($sound = $sounds->last()) {
  $data['audio'] = ($file = $sound->audio()->toFile()) ?  Url::path($file->url()) : null;
}