How to duplicate a matrix field programatically in Craft 3.1? Is there a "Craft" way of handling this in 3.1?

Solutions to this question on SE are based on older versions of Craft which no longer work.

Custom fields can be duplicated by doing:

$newEntry-&gt;customFieldHandle = $masterEntry-&gt;customFieldHandle;


I've tested this with Plain Text, Number, Dropdown, Date/Time, Entries fields and it works fine.

I tried this with a matrix field (not expecting it to work, as I appreciate Matrix fields are handled differently). The matrix content and fields are copied across when a newEntry is generated, but is deleted from the masterEntry.

Example module:

protected static function createNewEntry()
{
    Event::on(
        Elements::class,
        Elements::EVENT_AFTER_SAVE_ELEMENT,
        function(ElementEvent $event) {

            // Ignore any element that is not an entry
            if (!($event-&gt;element instanceof Entry)) {
                return;
            }

            // Ignore entries that are new because they have no id
            if ($event-&gt;isNew) {
                return;
            }

            // Fetch current entry and assign siteid
            $masterEntry = Craft::$app-&gt;entries-&gt;getEntryById($event-&gt;element-&gt;id, $event-&gt;element-&gt;siteId);

            // Basic Craft fields...
            $newEntry = new Entry();
            $newEntry-&gt;sectionId = $masterEntry-&gt;sectionId;
            // more craft fields here...

            // Custom fields 
            $newEntry-&gt;contentLongtitle = $masterEntry-&gt;contentLongtitle;
            // more craft custom fields here...

            // Matrix field 
            // Doing this copies the matrix content to newEntry
            // but deletes it from masterEntry
            $newEntry-&gt;matrixSchedule = $masterEntry-&gt;matrixSchedule;

            $success = Craft::$app-&gt;elements-&gt;saveElement($newEntry);
            // Handle success/failure logic here...

        }
    );
}
I've just found this: https://craftcms.stackexchange.com/a/25961/9344.

After reading Robins comments, I can see where I was going wrong.

My working example code now looks like this:

protected static function createNewEntry()
{
    Event::on(
        Elements::class,
        Elements::EVENT_AFTER_SAVE_ELEMENT,
        function(ElementEvent $event) {

            // Ignore any element that is not an entry
            if (!($event-&gt;element instanceof Entry)) {
                return;
            }

            // Ignore entries that are new because they have no id
            if ($event-&gt;isNew) {
                return;
            }

            // Fetch current entry and assign siteid
            $masterEntry = Craft::$app-&gt;entries-&gt;getEntryById($event-&gt;element-&gt;id, $event-&gt;element-&gt;siteId);

            // Fetch matrix fields by handle
            $masterEntryMatrix = Craft::$app-&gt;getFields()-&gt;getFieldByHandle('matrixSchedule');
            // get the existing matrixSchedule value
            $masterEntryMatrixQuery = $masterEntry-&gt;getFieldValue('matrixSchedule');
            // serialize the data in order to get an array
            $masterEntryMatrixSerialized = $masterEntryMatrix-&gt;serializeValue($masterEntryMatrixQuery, $masterEntry);

            // Basic Craft fields...
            $newEntry = new Entry();
            $newEntry-&gt;sectionId = $masterEntry-&gt;sectionId;
            // more craft fields here...

            // Custom fields 
            $newEntry-&gt;contentLongtitle = $masterEntry-&gt;contentLongtitle;
            // more craft custom fields here...

            // Matrix field 
            $newEntry-&gt;setFieldValue('matrixSchedule', $masterEntryMatrixSerialized);

            $success = Craft::$app-&gt;elements-&gt;saveElement($newEntry);
            // Handle success/failure logic here...

        }
    );
}