1

On my craft commerce project i eager-load categories which belong to a prodcut.

in my product template i do for eager -loading:

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

Before i added this eager-loading i checked if a certain categroy exists in a product to change the sytling:

{% if product.NameOfproductCategory.id('9999').exists() %}
    <div class="newproduct">
    </div>
{% endif %}

now with this eager-loading i get this error and i dont know how to solve it.

Impossible to invoke a method ("id") on an array.

1 Answer 1

1

Without eager-loading, accessing the categories field will return a CategoryQuery which you can add parameters to and execute with methods like exists(). With eager-loading, the categories are already loaded before you access them, so instead of a query you get an ElementCollection.

The element collection has some custom methods to be compatible with element queries, and extends Illuminate\Support\Collection, so you can use all the various collection methods.

You can check if the collection contains a collection with a specific ID like this:

{% if product.NameOfproductCategory.contains('id', '9999') %}
5
  • Thanks! One thing though, it's not .contains, but |contains. Can you adjust your answer, i cannot.
    – Henrik
    Commented Jul 21, 2023 at 7:45
  • @Henrik No, .contains is correct. As I said, since you have a collection, you can call any of it's instance methods. In this case, I'm calling the .contains method. You can also use |contains, which is the Craft filter of the same name.
    – MoritzLost
    Commented Jul 21, 2023 at 9:02
  • Ah, ok. .contains did not work in my case, but |contains did. That's why i thought you meant maybe the filter.
    – Henrik
    Commented Jul 24, 2023 at 5:12
  • @Henrik If .contains doesn't work, that means your categories were not eager-loaded! You can check whether the categories field gives you can ElementCollection or a CategoryQuery like this: {% dd product.NameOfProductCategory %}. If you get an CategoryQuery, that means your eager-loading is not working properly. But yes, |contains should work with arrays as well as collections, so it's safe to use if you're not sure if the field is eager-loaded or not. If your question is solved, don't forget to mark the answer as accepted.
    – MoritzLost
    Commented Jul 24, 2023 at 8:31
  • 1
    thanks! interessting. I used the blitz recommendations to speed up my a site and after i inserted the code in my question, the hint to eager-load my categories are gone and i noticed a huge decrease of db request in the debug toolbar. so i thought i successfully eager-loaded. have to look to that again then.
    – Henrik
    Commented Jul 24, 2023 at 8:53

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.