Cms: Deprecation error when trying to iterate eager loaded array without .all()

Created on 4 Sep 2018  Â·  13Comments  Â·  Source: craftcms/cms

Description

When looping through an eager loaded collection of objects, a deprecation error is shown for not using .all(). However, when .all() is added to the array, the error Impossible to invoke a method ("all") on an array. is shown.

Steps to reproduce

  1. Eager load categories for posts, e.g.
{% set posts = craft.entries({
    section: 'posts',
    with: ['thumbnailImage', 'readTime', 'postCategories', 'postTypes']
}) %}
  1. Try to loop through the postCategories, e.g. {%- for category in entry.postCategories.all() %} - the loop works without .all(), but a deprecation error is shown: Looping through element queries directly has been deprecated. Use the all() function to fetch the query results before looping over them.

Additional info

  • Craft version: 3.0.22

Most helpful comment

We added craft\services\Deprecator::$throwExceptions in 3.1.18, which may be helpful here. Instead of logging the deprecation error, an exception will be thrown, which will help you determine where and how they are occurring. (Only recommended for local environments.)

To enable, open config/app.php and add this:

return [
    '*' => [
        // global config...
    ],
    'dev' => [
        'components' => [
            'deprecator' => [
                'throwExceptions' => true,
            ],
        ],
    ],
];

All 13 comments

I’m not able to reproduce this, and pretty sure what you’re describing is impossible, as that deprecation error comes from craft\elements\db\ElementQuery, but when you eager-load elements, the result of entry.postCategories will be an array, not an ElementQuery object.

I’m guessing the actual deprecation error is getting triggered from somewhere else. Check Utilities → Deprecation Errors to see where it’s saying the origin of that error is.

Hi sorry for the delay on this. The deprecation error is reporting the exact line in the twig template that I mentioned in my original post, i.e.

/*****/templates/components/_entryGrid.twig:31

Line 31 is:

{%- for category in entry.postCategories %}

and as I say, if I add .all to that line, the error is shown. Not really sure where to go from here or what I'm doing wrong.

(I should also say, the same deprecation error appears in many places in my twig templates. In each case, adding all just errors.)

@howells can you send a database backup, your template files, and your composer.json and composer.lock files over to [email protected]?

@brandonkelly done - many thanks!

@howells Did you get this sorted, as I have been having the issues on multiple sites, even with Craft 3.4.5

@zizther no, it was never resolved

We added craft\services\Deprecator::$throwExceptions in 3.1.18, which may be helpful here. Instead of logging the deprecation error, an exception will be thrown, which will help you determine where and how they are occurring. (Only recommended for local environments.)

To enable, open config/app.php and add this:

return [
    '*' => [
        // global config...
    ],
    'dev' => [
        'components' => [
            'deprecator' => [
                'throwExceptions' => true,
            ],
        ],
    ],
];

nice aid...

Checking in with the same issue.

I'm simply eager loading a set of categories, so I can't use .all().

{% set films = craft.entries({
  section: 'films',
  with: ['relatedTopics']
}) %}

Inside my paginated films list I'm outputting categories with each film.

{% set relatedTopics = film.relatedTopics %}
{% if relatedTopics %}
  <ul>
    {% for topic in relatedTopics %}
      <li><a href="{{ topic.url }}">{{ topic.title }}</a></li>
    {% endfor %}
  </ul>
{% endif %}

Debug toolbar tells me that I need to use .all() in my categories loop.

Craft 3.4.8

This is a similar scenario to examples of this issue I have had

@jsunsawyer @zizther Please set 'throwExceptions' => true per my last comment, and then check the stack trace when the exception gets thrown. If it looks like Craft is the culprit, find the error in storage/logs/web.log and post the stack trace that follows.

@brandonkelly After a bit more digging, we figured out what was causing the issue.

We were doing a separate query for featured films that later get excluded from our normal films query. So our normal query had eager loading setup, while the other didn't, but both were using the same film widget component.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bitboxfw picture bitboxfw  Â·  3Comments

angrybrad picture angrybrad  Â·  3Comments

angrybrad picture angrybrad  Â·  3Comments

timkelty picture timkelty  Â·  3Comments

michaelhue picture michaelhue  Â·  3Comments