Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

benf\neo\elements\Block::useMemoized(): Argument #1 ($use) must be of type Illuminate\Support\Collection|array|bool, benf\neo\elements\db\BlockQuery #881

Closed
rjgux opened this issue Apr 18, 2024 · 1 comment
Labels
bug report status: external cause A bug report that was caused by behaviour external to this project bug report

Comments

@rjgux
Copy link

rjgux commented Apr 18, 2024

Bug Description

Hello,

Firstly apologies if this isn't a a bug and just an issue with our implementation of eager loading/useMemoized. We've run an upgrade from Craft 3 to Craft 4 and updated Neo in the process. In our templates we have the following -

{% for block in entry.contentBuilder %}}
    {% do block.useMemoized(entry.contentBuilder) %}}
{% endfor %}

{% for block in entry.contentBuilder.level(1).all() %}
...
{% endfor %}

After performing the upgrade to Craft 4, we get a TypeError -

benf\neo\elements\Block::useMemoized(): Argument #1 ($use) must be of type Illuminate\Support\Collection|array|bool, benf\neo\elements\db\BlockQuery given, called in /var/www/html/vendor/twig/twig/src/Extension/CoreExtension.php on line 1635

Stack trace -

TypeError: benf\neo\elements\Block::useMemoized(): Argument #1 ($use) must be of type Illuminate\Support\Collection|array|bool, benf\neo\elements\db\BlockQuery given, called in /var/www/html/vendor/twig/twig/src/Extension/CoreExtension.php on line 1635 and defined in /var/www/html/vendor/spicyweb/craft-neo/src/elements/Block.php:732
Stack trace:
#0 /var/www/html/vendor/twig/twig/src/Extension/CoreExtension.php(1635): benf\neo\elements\Block->useMemoized()
#1 /var/www/html/vendor/craftcms/cms/src/helpers/Template.php(129): twig_get_attribute()
#2 /var/www/html/storage/runtime/compiled_templates/86/86c81dea0af1de11fa73a63f684f487c.php(49): craft\helpers\Template::attribute()
#3 /var/www/html/vendor/twig/twig/src/Template.php(394): __TwigTemplate_666e075b3dda1ce13f2932cd6735b674->doDisplay()
#4 /var/www/html/vendor/twig/twig/src/Template.php(367): Twig\Template->displayWithErrorHandling()
#5 /var/www/html/storage/runtime/compiled_templates/62/62e109b89cf039212ee93d8231dfe6d9.php(57): Twig\Template->display()
#6 /var/www/html/vendor/twig/twig/src/Template.php(394): __TwigTemplate_553d3946f4de2f1dc2409699e72bccab->doDisplay()
#7 /var/www/html/vendor/twig/twig/src/Template.php(367): Twig\Template->displayWithErrorHandling()
#8 /var/www/html/storage/runtime/compiled_templates/85/8563aec7971a923734be1136c8ebe0ea.php(74): Twig\Template->display()
#9 /var/www/html/vendor/twig/twig/src/Template.php(171): __TwigTemplate_5e868af42e446739aa71ac3db42987a5->block_content()
#10 /var/www/html/storage/runtime/compiled_templates/13/13b181f04ba803bf9791c9d929cc7856.php(495): Twig\Template->displayBlock()
#11 /var/www/html/vendor/twig/twig/src/Template.php(394): __TwigTemplate_a9089982caac22f8eb2fe10cbfd5ef28->doDisplay()
#12 /var/www/html/vendor/twig/twig/src/Template.php(367): Twig\Template->displayWithErrorHandling()
#13 /var/www/html/storage/runtime/compiled_templates/85/8563aec7971a923734be1136c8ebe0ea.php(52): Twig\Template->display()
#14 /var/www/html/vendor/twig/twig/src/Template.php(394): __TwigTemplate_5e868af42e446739aa71ac3db42987a5->doDisplay()
#15 /var/www/html/vendor/twig/twig/src/Template.php(367): Twig\Template->displayWithErrorHandling()
#16 /var/www/html/storage/runtime/compiled_templates/da/da600c8c5451463899d5a4393a1553b0.php(53): Twig\Template->display()
#17 /var/www/html/vendor/twig/twig/src/Template.php(394): __TwigTemplate_09b4492ff039745f6288abd8c45c1d15->doDisplay()
#18 /var/www/html/vendor/twig/twig/src/Template.php(367): Twig\Template->displayWithErrorHandling()
#19 /var/www/html/vendor/twig/twig/src/Template.php(379): Twig\Template->display()
#20 /var/www/html/vendor/twig/twig/src/TemplateWrapper.php(38): Twig\Template->render()
#21 /var/www/html/vendor/twig/twig/src/Environment.php(280): Twig\TemplateWrapper->render()
#22 /var/www/html/vendor/craftcms/cms/src/web/View.php(482): Twig\Environment->render()
#23 /var/www/html/vendor/craftcms/cms/src/web/View.php(535): craft\web\View->renderTemplate()
#24 /var/www/html/vendor/craftcms/cms/src/web/TemplateResponseFormatter.php(57): craft\web\View->renderPageTemplate()
#25 /var/www/html/vendor/yiisoft/yii2/web/Response.php(1100): craft\web\TemplateResponseFormatter->format()
#26 /var/www/html/vendor/craftcms/cms/src/web/Response.php(337): yii\web\Response->prepare()
#27 /var/www/html/vendor/yiisoft/yii2/web/Response.php(340): craft\web\Response->prepare()
#28 /var/www/html/vendor/yiisoft/yii2/base/Application.php(390): yii\web\Response->send()
#29 /var/www/html/public/index.php(21): yii\base\Application->run()
#30 {main}

Steps to reproduce

  1. Add the following to a template -
{% for block in entry.contentBuilder %}}
    {% do block.useMemoized(entry.contentBuilder) %}}
{% endfor %}
  1. Navigate to template

Expected behaviour

Eager loaded elements/no type error

Neo version

4.1.2

Craft CMS version

4.8.9

What is the affected Neo field's propagation method?

No response

Does this issue involve templating, and if so, is eager-loading used?

This is a templating issue, and eager loading is used

@ttempleton
Copy link
Contributor

This is the expected behaviour - useMemoized() doesn't accept an unexecuted Neo block query, which is what entry.contentBuilder is if the Neo field itself hasn't been eager loaded.

You would either need to execute the block query beforehand:

{% set blocks = entry.contentBuilder.all() %}

{% for block in blocks %}
    {% do block.useMemoized(blocks) %}
{% endfor %}

{% for block in blocks %}
  {% if block.level == 1 %}
    {# ... #}
  {% endif %}
{% endfor %}

Or you could eager load the Neo field:

{% do craft.app.elements.eagerLoadElements(
    className(entry),
    [entry],
    ['contentBuilder']
) %}

{# entry.contentBuilder is now a `craft\elements\ElementCollection` of blocks #}
{% for block in entry.contentBuilder %}
    {% do block.useMemoized(entry.contentBuilder) %}
{% endfor %}

{% for block in entry.contentBuilder %}
  {% if block.level == 1 %}
    {# ... #}
  {% endif %}
{% endfor %}

Note that, in both cases, your check for top level blocks will need to either be moved inside the for loop (as shown in the above examples), or could be done using the filter filter:

{% for block in blocks|filter(block => block.level == 1) %}

@ttempleton ttempleton closed this as not planned Won't fix, can't repro, duplicate, stale Apr 20, 2024
@ttempleton ttempleton added bug report status: external cause A bug report that was caused by behaviour external to this project and removed bug report status: new labels Apr 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug report status: external cause A bug report that was caused by behaviour external to this project bug report
Projects
None yet
Development

No branches or pull requests

2 participants