1

i try to get blockMatrix value with different way(.one() & .all()) in the same page (this page consists of several templates) but the result is weird. Here how i do it:

i have a blockMatrix("mediaContentComponent") with 2 types:

  1. textContentComponent => only plain text field
  2. imageContentComponent => only asset field

At first value, i try to get only the first textContentComponent value in blockMatrix with entry.mediaContentComponent.type('textContentComponent').one(), This query will run in base.twig.

then on second value, i try to get all the blockMatrix values with entry.mediaContentComponent.all(), this query will run in content.twig.

Now after all query is running here is the weird result, the first value didn't have any problem but the second value didn't have any imageContentComponent and only have textContentComponent. I am curious, is this expected behaviour that Craft have?

Note:

  1. the blockMatrix value is added randomly by editor. And here is how i handle the second value:
{% set contents = entry.mediaContentComponent.all() %}

{% for content in contents %}
   {% switch content.type %}
      {% case 'imageContentComponent' %}
    
      {% case 'textContentComponent' %}

    {% endswitch %}
{% endfor %}

1 Answer 1

2

It is indeed confusing behaviour... The reason why it's happening, along with a handful of solutions, is outlined in the answers to this question: Offset setting a limit?

As I mentioned in my answer to that question, if possible it would be best to avoid multiple roundtrips to the database, fetching your data once only and then using filters to filter down the full result set later, but in some cases that might not be easy or possible... in which case clone() is a solution, or nullifying the parameters that you set earlier, as per Josh's answer.

3
  • Hi @JamesSmith using clone() is work with my code, thank for your answer. Actually i never checking documentation about Upgrading from Craft 2 since i have never use Craft 2 from the start i use Craft.
    – Nixxian365
    Commented Mar 15 at 2:28
  • "if possible it would be best to avoid multiple roundtrips to the database, fetching your data once only and then using filters to filter down the full result set later" When you mention this, does that mean i need to create a variable entry.mediaContentComponent.all() in base.twig, and than pass it to content.twig?
    – Nixxian365
    Commented Mar 15 at 2:32
  • Yes that's right. Depending on how your templates are organised it might not be easy, however, so you'd need to make a judgment call on whether the optimisation is worth it. If content.twig extends base.twig, you wouldn't need to explicitly pass a variable - it'll automatically be able to access it through inheritance. Commented Mar 15 at 9:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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