Trouble with FieldItemList::view I have a custom content entity that renders fine in its page view and form. I'm now trying to view one of its fields in a table using an EntityListBuilder, but the following code throws an error message:

public function buildRow(EntityInterface $entity) {
  $row['id'] = $entity-&gt;id();
  $row['email'] = $entity-&gt;email-&gt;view();

  return $row + parent::buildRow($entity);
}


Results in:


  Fatal error: Call to undefined method
  Drupal\my_module\Entity\MyEntity::render() in
  /.../core/lib/Drupal/Core/Template/Attribute.php on line 294


Apparently the view builder expects a render() method, which I do not have, and which I do not want to implement, since the entity renders fine otherwise...

Also tried EntityViewBuilder::viewField() with no success.

Even when I'm viewing a node instead of my custom entity, I get the same message.
The function buildRow returns a render array. You can put simple strings directly in the array, because later it will be put in another html structure like a table. An example from core, where it is used both ways (CommentTypeListBuilder.php):

public function buildRow(EntityInterface $entity) {
    $row['type'] = $entity-&gt;label();
    $row['description']['data'] = ['#markup' =&gt; $entity-&gt;getDescription()];
    return $row + parent::buildRow($entity);
  }


So using the '#markup' element is optional. You can use it to be on the safe side, when you don't know how your render array is processed.

For complex elements you need a render element. The method view() would generates this:

$row['email'] = $entity-&gt;email-&gt;view();


But this does not work. The problem seems to be in the custom entity. According to the error message there is a call to an undefined method render, which should be defined in MyEntity. Your entity does not know how to handle the email field.

If you don't want to theme the field, you can use the value as markup:

$row['email']['#markup'] = $entity-&gt;email-&gt;value;


Or you can put the field as an object:

$row['email'] = $entity-&gt;email;


Or you can build your own render array, for example as a link:

$row['title'] = array(
      '#type' =&gt; 'link',
      '#title' =&gt; $entity-&gt;label(),
      '#url' =&gt; $uri,
    );