How to change an entry's slug on EVENT_AFTER_SAVE_ELEMENT? My entries' titles are auto-generated from several fields values on first save.

When one of these fields values change, I would like to update the auto-generated slug also:

Event::on(
    \craft\services\Elements::class,
    \craft\services\Elements::EVENT_AFTER_SAVE_ELEMENT,
    function (Event $event) {
        $entry = Entry::find()
            -&gt;id($event-&gt;element-&gt;id)
            -&gt;one();

        if ([] !== $entry) {
            $title = craft\helpers\StringHelper::toAscii($entry-&gt;id.'-'.$entry-&gt;title);
            $title = craft\helpers\StringHelper::toLowerCase($title);
            $title = str_replace(' ', '-', $title);

            //  I tried this below, but none works
            $entry-&gt;slug = $title; // ⬅️ Not working
            $entry-&gt;setFieldValue('slug', $title); // ⬅️ Error
            Craft::$app-&gt;elements-&gt;saveElement($entry); // ⬅️ Infinite loop
            $event-&gt;element-&gt;slug = $event-&gt;element-&gt;id; // ⬅️ Not working
        }
    }
);


Unfortunately, none of these methods works. Any idea how to achieve this?
You can change the value in the DB directly instead of using the Elements service

$entry = $event-&gt;element;
$elementId = $entry-&gt;id;
$siteId = $entry-&gt;siteId;
Craft::$app-&gt;getDb()-&gt;createCommand()
    -&gt;update(
        '{{%elements_sites}}',
        ['slug' =&gt; ElementHelper::createSlug('new-slug')],
        [
            'elementId' =&gt; $elementId,
            'siteId'    =&gt; $siteId
        ]
    )-&gt;execute();


By the way the following condition [] !== $entry won't be any good when you fetch an element with one() because one returns an object of instance ElementInterface or null but never an empty array. You can check !== null instead and if you fetch things via all you can perform an empty check if( empty($entries) === false)