1

I have a component that accepts both hardcoded objects and entry queries. This allows us to have components that can be used independent of the database.

Hardcode include:

{% include '_components/callToAction' with {
    headline: 'Hardcode call to CTA Headline',
    body: 'Hardcode call to CTA',
    items: [
      { name: 'item1'},
      { name: 'item2'} 
    ]
} %}

db include:

{% include '_components/callToAction' with {
    entry: entry.callToAction
} %}

Component:

{% set component = {
  headline: headline ?? entry.headline ?? null,
  body: body ?? entry.body ?? null,
  items: items ?? entry.items ?? null
} %}

<h1>{{ component.headline }}</h1>
<p>{{ component.body }}</p>

{% for item in component.items %}
  {{ item.name }}
{% endfor %}

Both those work fine, but with Craft 3 we're getting deprecation errors for not using .all() when it is an element query which is drastically increasing our db queries on the pages that use several of these components.

  • And why do you refuse to execute the query? Seems no difference to me. Of course it makes sense in certain scenarios, but not in yours – Robin Schambach Jun 5 '18 at 14:04
  • Not sure I understand, but items in the component won't work on the hardcoded include with .all() but it throws an error without it when it is run with the db include. – Jeremy A Jun 5 '18 at 14:52
  • You can either check if the current instance of items is an element of type ElementQuery or you pass the related items within it. entry: entry.callToAction, items: entry.items.all() or items: items ?? entry.items.all() ?? null I just want to understand why you don't want to execute it – Robin Schambach Jun 5 '18 at 15:23
  • @RobinSchambach - I do want to execute it, I updated my example code which I think is where the confusion is coming from. – Jeremy A Jun 6 '18 at 11:50
1

Instead of trying to loop through an object (your Query) you could just execute it

{% set component = {
    headline: headline ?? entry.headline ?? null,
    body: body ?? entry.body ?? null,
    items: items ?? entry.items.all() ?? null
} %}

<h1>{{ component.headline }}</h1>
<p>{{ component.body }}</p>

{% for item in component.items %}
    {{ item.name }}
{% endfor %}

or if that doesn't fit your case, you can do it before

{% set relatedEntry = entry.callToAction.one() %}
{% include '_components/callToAction' with {
    entry: relatedEntry,
    items: relatedEntry.items.all()
} %}

You could as well check if your variable is an object of type EntryQuery

{% if className(entry) == 'craft\elements\db\EntryQuery' %}
    {% set entry = entry.one() %}
{% endif %}

Note: since you had multiple of these deprecated errors I wasn't exactly sure which one you wanted to "solve" and which one is "intended"

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.