<p>You're calling <code>implode</code> on a single description, this won't work. You need to map the array of <code>LineItem</code> objects to an array of strings (containing the description), then call <code>implode</code> on that.</p>
<p>It should work like this:</p>
<pre class="lang-php prettyprint-override"><code>$lineItems = $order-&gt;lineItems;
$descriptions = array_column($lineItems, 'description');
$event-&gt;html = implode(' | ', $descriptions);
</code></pre>
<p><a href="https://www.php.net/manual/en/function.array-column.php" rel="nofollow noreferrer"><code>array_column</code></a> works well if you want a single property (like the description) from all line items. If you want multiple properties or a custom format, you can use <a href="https://www.php.net/manual/en/function.array-map.php" rel="nofollow noreferrer"><code>array_map</code></a> instead to map the array of line items to an array of strings with a custom format:</p>
<pre class="lang-php prettyprint-override"><code>$lineItems = $order-&gt;lineItems;
$descriptions = array_map(
    fn($lineItem) =&gt; &quot;{$lineItem-&gt;description} ({$lineItem-&gt;qty})&quot;,
    $lineItems,
);
$event-&gt;html = implode(' | ', $descriptions);
</code></pre>
<p>This will result in something like <code>First item (2) | Second item (1)</code>.</p>

CC BY-SA 4.0
2022-04-07T22:37:41.370Z
Thank you! So now if I wanted to also show the quantity for each line item, how could I do that?
`$lineItems = $order->lineItems;
$descriptions = array_column($lineItems, 'description');
$quantity = array_column($lineItems, 'qty');
$event->html = implode(' | ', $descriptions) . implode('', $quantity);`

This ends up like 'First Item | Second Item21' (which makes sense)
supazu
CC BY-SA 4.0
2022-04-08T08:46:21.033Z
@brynli64 Use array_map instead of array_column, I've updated my answer with a code example for that!
MoritzLost
CC BY-SA 4.0
2022-04-08T18:26:20.203Z
Updoot for a really elegant use of arrow functions!
August Miller
CC BY-SA 4.0
2022-04-08T23:20:21.440Z
That's brilliant, thanks @MoritzLost!
supazu
CC BY-SA 4.0
2022-04-07T13:04:51.253Z
2022-04-08T08:45:33.157Z
2022-04-08T08:45:33.157Z
MoritzLost
<p>Second to my <a href="https://craftcms.stackexchange.com/questions/39288/get-order-shipping-address-in-module">other question</a> about adding a column to the orders index, I would now like to add a column looping over the products in the order.</p>
<p>How can I do that when then <a href="https://docs.craftcms.com/api/v3/craft-events-setelementtableattributehtmlevent.html" rel="nofollow noreferrer"><code>SetElementTableAttributeHtmlEvent</code></a> <code>html</code> property wants a string?</p>
<pre><code>function (SetElementTableAttributeHtmlEvent $event) {
    $order = $event-&gt;sender;
    if ($event-&gt;attribute === 'products') {
        $lineItems = $order-&gt;lineItems;
        foreach ($lineItems as $lineItem) {
            $event-&gt;html = $lineItem-&gt;description;
        }
    }
}
</code></pre>
<p>I thought maybe something like this would work <code>$event-&gt;html = implode('|', $lineItem-&gt;description);</code> but I get <code>TypeError: implode(): Argument #2 ($array) must be of type ?array, string given</code></p>

<modules>
`SetElementTableAttributeHtmlEvent` with an array
# `SetElementTableAttributeHtmlEvent` with an array

(Asked by: username_0 on 2022-04-07)

Second to my other question about adding a column to the orders index, I would now like to add a column looping over the products in the order.
How can I do that when then SetElementTableAttributeHtmlEvent html property wants a string?
function (SetElementTableAttributeHtmlEvent $event) {
    $order = $event->sender;
    if ($event->attribute === 'products') {
        $lineItems = $order->lineItems;
        foreach ($lineItems as $lineItem) {
            $event->html = $lineItem->description;
        }
    }
}

I thought maybe something like this would work $event->html = implode('|', $lineItem->description); but I get TypeError: implode(): Argument #2 ($array) must be of type ?array, string given

**Tags:** modules


---

## 1 answers

### Answer by username_1 on 2022-04-07. Score: 3 | Accepted answer

You're calling implode on a single description, this won't work. You need to map the array of LineItem objects to an array of strings (containing the description), then call implode on that.
It should work like this:
$lineItems = $order->lineItems;
$descriptions = array_column($lineItems, 'description');
$event->html = implode(' | ', $descriptions);

array_column works well if you want a single property (like the description) from all line items. If you want multiple properties or a custom format, you can use array_map instead to map the array of line items to an array of strings with a custom format:
$lineItems = $order->lineItems;
$descriptions = array_map(
    fn($lineItem) => "{$lineItem->description} ({$lineItem->qty})",
    $lineItems,
);
$event->html = implode(' | ', $descriptions);

This will result in something like First item (2) | Second item (1).

> **Comments:**
> **username_0**: Thank you! So now if I wanted to also show the quantity for each line item, how could I do that? `$lineItems = $order->lineItems; $descriptions = array_column($lineItems, 'description'); $quantity = array_column($lineItems, 'qty'); $event->html = implode(' | ', $descriptions) . implode('', $quantity);`  This ends up like 'First Item | Second Item21' (which makes sense)  
> **username_1**: @brynli64 Use array_map instead of array_column, I've updated my answer with a code example for that!  
> **username_2**: Updoot for a really elegant use of arrow functions!  
> **username_0**: That's brilliant, thanks @username_1!  

---

