<p>You are correct in your assumption, the element query will not take an array as values, and they should be flat out.</p>
<p>In Craft 4, all element queries can now be returned as collections. So you can leverage their functionality to actually make this easier.</p>
<pre><code>{# array #}
{% set queryFeaturedEvents = entry.featuredEventsLimited.limit(3).ids() %}

{# array #}
{% set queryEventsOngoing = craft.entries.section('events')
    .type(['event', 'uitEvent'])
    .id(['not', queryFeaturedEvents.ids()])
    .datetimeStart('&lt;= ' ~ now | date('Y-m-d') | date('c'))
    .datetimeEnd('&gt;= ' ~ now | date('Y-m-d') | date('c'))
    .ids()
%}

{% set parameter = collect(['not']) %}

{% set excludedIds = parameter.merge(queryFeaturedEvents).merge(queryEventsOngoing) %}

</code></pre>
<p>The above should generate your array as <code>['not', 2849138, 2932212, 2464675]</code></p>
<p>And then you should be simply able to do:</p>
<pre><code>{% set queryEventsUpcoming = craft.entries.section('events')
    .type(['event', 'uitEvent'])
    .id(excludedIds)
    .datetimeStart('&gt;= ' ~ now | date('Y-m-d') | date('c'))
    .collect()
%}
</code></pre>
<p>Hope this helps!</p>

CC BY-SA 4.0
2023-03-08T13:56:13.057Z
Thank you for the help. Unfortunatly, I'm still getting errors. Now I'm getting 'Impossible to invoke a method ("collect") on an array.' , featuredEventsLimited is an entry-field type
Julie Velghe
CC BY-SA 4.0
2023-03-08T13:58:58.703Z
Where exactly (which line) would you get this error right now? I'm assuming it's on the `parameter` variable?
Michael Thomas
CC BY-SA 4.0
2023-03-08T14:15:50.730Z
I don't think it's accurate to say that `In Craft 4, all element queries are now returned as collections` - they're only returned as collections if you use `.collect()` instead of one of the standard execution methods like `.one()` or `.all()`... or in this case `.ids()`. The exception is for eager loaded elements, which are always returned as collections, which still trips me up.
James Smith
CC BY-SA 4.0
2023-03-08T14:40:43.320Z
its the .ids().collect() on the first line of code that went wrong for me. If I change the first line of code to just .ids() and then use the 'set parameter = collect logic' for that first block, I can get it to work
Julie Velghe
CC BY-SA 4.0
2023-03-08T14:49:25.210Z
I edited my answer. You are right tho `.ids()` are automatically arrays.
Thank you for pointing out my choice of words @JamesSmith. 

Although Element Queries are indeed just returned as collections when `.collect()` is used. Imo it's a good practice to use them as they bring so many benefits to the table!
Michael Thomas
CC BY-SA 4.0
2023-03-09T14:22:03.433Z
Hi @MichaelThomas - if this answer worked for you please don't forget to mark it as "the answer" here on Stack Exchange. Thank you!
cherrykoda
CC BY-SA 4.0
2023-03-16T11:55:54.073Z
@cherrykoda I think you meant to tag julie-velghe. I don't think I can mark my own answer as "the answer" ;)
Michael Thomas
CC BY-SA 4.0
2023-03-16T20:05:44.993Z
YUP, i'll get the hang of this! @JulieVelghe if you found success with Michael's answer please remember to mark his solution as the accepted answer :)
cherrykoda
CC BY-SA 4.0
2023-03-08T13:21:23.550Z
2023-03-08T14:47:51.277Z
2023-03-08T14:47:51.277Z
Michael Thomas
<p>I'm slightly surprised this worked before, as .ids() does return an array and I didn't think <code>('not', [1,2,...])</code> was valid in 3.x</p>
<p>Anyways, wrap queryFeauturedEvents.ids() in implode() and you should be good!</p>
<p><a href="https://www.php.net/manual/en/function.implode.php" rel="nofollow noreferrer">https://www.php.net/manual/en/function.implode.php</a></p>

CC BY-SA 4.0
2023-03-08T14:49:43.383Z
yeah, beats me why it worked before. As I'm doing this in twig, implode is not available to me (tried the twig join, did not work either). Using that twig 'collect' function did the trick.
Julie Velghe
CC BY-SA 4.0
2023-03-08T14:51:13.830Z
It shouldn't have worked in Craft 3 either, that is correct. But I think it's nicer to simply use the new Collection properties which are baked in rather than using native PHP functions tho!
Michael Thomas
CC BY-SA 4.0
2023-03-08T15:55:30.010Z
Collections are great. Not sure why I read this as php in my head, sorry!
cherrykoda
CC BY-SA 4.0
2023-03-08T14:28:04.807Z
2023-03-08T14:28:04.807Z
cherrykoda
<p>I've upgraded a project to craft 4, and now I'm getting an error on my entry query.</p>
<p>Below is the code I have:</p>
<pre><code>{% set queryFeaturedEvents = entry.featuredEventsLimited.limit(3) %}

{% set queryEventsOngoing = craft.entries.section('events')
    .type(['event', 'uitEvent'])
    .id(['not', queryFeaturedEvents.ids()])
    .datetimeStart('&lt;= ' ~ now | date('Y-m-d') | date('c'))
    .datetimeEnd('&gt;= ' ~ now | date('Y-m-d') | date('c')) %}

{% set queryEventsUpcoming = craft.entries.section('events')
    .type(['event', 'uitEvent'])
    .id(['not', queryFeaturedEvents.ids() | merge(queryEventsOngoing.ids())])
    .datetimeStart('&gt;= ' ~ now | date('Y-m-d') | date('c')) %}
</code></pre>
<p>I get an array to string conversion error, that seemingly gets triggered by the queryEventsOngoing.ids() (when I put that in a seperate variable, the code stops there.)
I have a feeling it has something to do with my id exclusion in the first query. When I look further into the error stack I see following:
in <code>C:\Users\julie\Documents\CabinetC\Repos\merode\vendor\craftcms\cms\src\elements\db\ElementQuery.php at line 1330– craft\helpers\Db::parseNumericParam('elements.id', ['not', [2849138, 2932212, 2464675]])</code>
I would think that it should be ['not', 2849138, 2932212, 2464675] ? The code did work with craft 3 so I'm a bit at a loss as to why it doesn't work any more.
Anyone have any ideas on how I can fix this?</p>

<entries><elementquery><exclude>
Getting an error on element query after upgrade to craft 4
# Getting an error on element query after upgrade to craft 4

(Asked by: username_0 on 2023-03-08)

I've upgraded a project to craft 4, and now I'm getting an error on my entry query.
Below is the code I have:
{% set queryFeaturedEvents = entry.featuredEventsLimited.limit(3) %}

{% set queryEventsOngoing = craft.entries.section('events')
    .type(['event', 'uitEvent'])
    .id(['not', queryFeaturedEvents.ids()])
    .datetimeStart('<= ' ~ now | date('Y-m-d') | date('c'))
    .datetimeEnd('>= ' ~ now | date('Y-m-d') | date('c')) %}

{% set queryEventsUpcoming = craft.entries.section('events')
    .type(['event', 'uitEvent'])
    .id(['not', queryFeaturedEvents.ids() | merge(queryEventsOngoing.ids())])
    .datetimeStart('>= ' ~ now | date('Y-m-d') | date('c')) %}

I get an array to string conversion error, that seemingly gets triggered by the queryEventsOngoing.ids() (when I put that in a seperate variable, the code stops there.)
I have a feeling it has something to do with my id exclusion in the first query. When I look further into the error stack I see following:
in C:\Users\julie\Documents\CabinetC\Repos\merode\vendor\craftcms\cms\src\elements\db\ElementQuery.php at line 1330– craft\helpers\Db::parseNumericParam('elements.id', ['not', [2849138, 2932212, 2464675]])
I would think that it should be ['not', 2849138, 2932212, 2464675] ? The code did work with craft 3 so I'm a bit at a loss as to why it doesn't work any more.
Anyone have any ideas on how I can fix this?

**Tags:** entries, elementquery, exclude


---

## 2 answers

### Answer by username_1 on 2023-03-08. Score: 2

You are correct in your assumption, the element query will not take an array as values, and they should be flat out.
In Craft 4, all element queries can now be returned as collections. So you can leverage their functionality to actually make this easier.
{# array #}
{% set queryFeaturedEvents = entry.featuredEventsLimited.limit(3).ids() %}

{# array #}
{% set queryEventsOngoing = craft.entries.section('events')
    .type(['event', 'uitEvent'])
    .id(['not', queryFeaturedEvents.ids()])
    .datetimeStart('<= ' ~ now | date('Y-m-d') | date('c'))
    .datetimeEnd('>= ' ~ now | date('Y-m-d') | date('c'))
    .ids()
%}

{% set parameter = collect(['not']) %}

{% set excludedIds = parameter.merge(queryFeaturedEvents).merge(queryEventsOngoing) %}


The above should generate your array as ['not', 2849138, 2932212, 2464675]
And then you should be simply able to do:
{% set queryEventsUpcoming = craft.entries.section('events')
    .type(['event', 'uitEvent'])
    .id(excludedIds)
    .datetimeStart('>= ' ~ now | date('Y-m-d') | date('c'))
    .collect()
%}

Hope this helps!

> **Comments:**
> **username_0**: Thank you for the help. Unfortunatly, I'm still getting errors. Now I'm getting 'Impossible to invoke a method ("collect") on an array.' , featuredEventsLimited is an entry-field type  
> **username_1**: Where exactly (which line) would you get this error right now? I'm assuming it's on the `parameter` variable?  
> **username_2**: I don't think it's accurate to say that `In Craft 4, all element queries are now returned as collections` - they're only returned as collections if you use `.collect()` instead of one of the standard execution methods like `.one()` or `.all()`... or in this case `.ids()`. The exception is for eager loaded elements, which are always returned as collections, which still trips me up.  
> **username_0**: its the .ids().collect() on the first line of code that went wrong for me. If I change the first line of code to just .ids() and then use the 'set parameter = collect logic' for that first block, I can get it to work  
> **username_1**: I edited my answer. You are right tho `.ids()` are automatically arrays. Thank you for pointing out my choice of words @JamesSmith.   Although Element Queries are indeed just returned as collections when `.collect()` is used. Imo it's a good practice to use them as they bring so many benefits to the table!  
> **username_3**: Hi @MichaelThomas - if this answer worked for you please don't forget to mark it as "the answer" here on Stack Exchange. Thank you!  
> **username_1**: @username_3 I think you meant to tag julie-velghe. I don't think I can mark my own answer as "the answer" ;)  
> **username_3**: YUP, i'll get the hang of this! @JulieVelghe if you found success with Michael's answer please remember to mark his solution as the accepted answer :)  

---

### Answer by username_3 on 2023-03-08. Score: 1

I'm slightly surprised this worked before, as .ids() does return an array and I didn't think `('not', [1,2,...])` was valid in 3.x

Anyways, wrap queryFeauturedEvents.ids() in implode() and you should be good!

<https://www.php.net/manual/en/function.implode.php>

> **Comments:**
> **username_0**: yeah, beats me why it worked before. As I'm doing this in twig, implode is not available to me (tried the twig join, did not work either). Using that twig 'collect' function did the trick.  
> **username_1**: It shouldn't have worked in Craft 3 either, that is correct. But I think it's nicer to simply use the new Collection properties which are baked in rather than using native PHP functions tho!  
> **username_3**: Collections are great. Not sure why I read this as php in my head, sorry!  

---

