<p>The documentation on this is a bit scattered about, it took me a while to get the whole picture as well. You need multiple pieces of information:</p>
<ol>
<li>The documentation on <a href="https://craftcms.com/docs/3.x/assets.html#querying-assets" rel="nofollow noreferrer">querying assets</a> only mentions <code>craft.assets()</code> as a way to query entries, which you would use to query assets <em>independently of an entry</em>.</li>
<li>Meanwhile, you can find the documentation on how to query assets from an entry field in the <a href="https://craftcms.com/docs/3.x/assets-fields.html#working-with-assets-field-data" rel="nofollow noreferrer">Asset Fields documentation</a>. The thing to realize here is that <code>entry.myFieldHandle</code> gives you a <a href="https://docs.craftcms.com/api/v3/craft-elements-db-assetquery.html" rel="nofollow noreferrer">craft\elements\db\AssetQuery</a> object, same as <code>craft.assets()</code>, but populated with where-clauses to get only assets selected for that field on that entry.</li>
<li>Finally, you need to look at the documentation for <a href="https://craftcms.com/docs/3.x/element-queries.html#executing-element-queries" rel="nofollow noreferrer">Element Queries</a>, which will give you the different options for executing element queries, including <a href="https://docs.craftcms.com/api/v3/craft-db-query.html#method-all" rel="nofollow noreferrer">AssetQuery::all()</a>. <a href="https://docs.craftcms.com/api/v3/craft-db-query.html#method-one" rel="nofollow noreferrer">AssetQuery::one()</a> is the one you're looking for, this will execute the query and return a single result element (or <code>null</code> if no results are found).</li>
</ol>
<p>Putting it all together, here's how you would access a single thumbnail in your code:</p>
<pre><code>{% set portfolioGrid = craft.entries().section('projects').all() %}
{% for portfolioTile in portfolioGrid %}
    {% set thumbnail = portfolioTile.projectThumbnail.one() %}

    {# AssetQuery::one may return null if the field is empty. #}
    {% if thumbnail %}
        {# Output the thumbnail. #}
    {% endif %}
{% endfor %}
</code></pre>

CC BY-SA 4.0
2021-06-08T12:58:05.897Z
I thought this as well but when I tried this approach I got a twig error, "Variable "projectThumbnail" does not exist." I added "{% set portfolioThumbnail = portfolioTile.projectThumbnail.one() %}" inside the grid for loop and changed the anchor tag to "<a href="{{ portfolioTile.url }}" class="portfolioTile{% if portfolioTile.featuredProject %} featuredProject{% endif %}"{% if projectThumbnail | length %} style="background-image: url('{{ projectThumbnail.getUrl }}'); background-size: cover;"{% endif %}>" to try to grab the thumbnail.
Stuart McCoy
CC BY-SA 4.0
2021-06-08T13:04:07.820Z
@StuartMcCoy You're setting `portfolioThumbnail` but trying to access the variable as `projectThumbnail` :-) If you use the correct variable name it will work! ANother thing: Instead of `{% if projectThumbnail | length %}`, use just `{% if projectThumbnail %}`, since `AssetQuery::one()` returns either a single Asset object or null, not an array.
MoritzLost
CC BY-SA 4.0
2021-06-08T14:00:03.617Z
Thanks. It's always something stupid or little that gets overlooked.
Stuart McCoy
CC BY-SA 4.0
2021-06-08T07:22:11.287Z
2021-06-08T07:22:11.287Z
MoritzLost
<p>I am wracking my brain here trying to understand the new documentation in Craft CMS 3 and the new way it handles assets from an entry. I have a page that creates a list of portfolio entries using thumbnails. The image is placed as a background-image using inline CSS and the div with the content appears on hover. The thumbnails are from a field in my entry called projectThumbnails. This field only allows a single image so pulling an array doesn't make sense, does it?</p>
<p>I got this working using a deprecated method (see code below) but I'd prefer to not have any deprecation warnings on my final site. The warning says &quot;Looping through element queries directly has been deprecated. Use the all() function to fetch the query results before looping over them.&quot; but adding .all() to the asset query doesn't seem to fix the issue. Is there a way to avoid creating the asset query and just use the entry query since the field already exists in the entry?</p>
<pre><code>
{% block main %}

{# Create entry queries #}
{% set portfolioGrid = craft.entries().section('projects').all() %}
{% set portfolioThumnbnails = craft.assets.volume('projectThumbnails') %}


{# Display the entries #}
&lt;section class=&quot;portfolioGrid&quot;&gt;
    {% for portfolioTile in portfolioGrid %}
    &lt;a href=&quot;{{ portfolioTile.url }}&quot; class=&quot;portfolioTile{% if portfolioTile.featuredProject %} featuredProject{% endif %}&quot;{% if portfolioTile.projectThumbnail | length %}{% for projectThumbnail in portfolioTile.projectThumbnail %} style=&quot;background-image: url('{{ projectThumbnail.getUrl }}'); background-size: cover;&quot;{% endfor %}{% endif %}&gt;
        &lt;div class=&quot;portfolioTileContent&quot;&gt;
            &lt;h1&gt;{{ portfolioTile.projectName }}&lt;/h1&gt;
            &lt;h2&gt;{{ portfolioTile.client.one.title }}&lt;/h2&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    {% endfor %}
&lt;/section&gt;

{% endblock %}
</code></pre>

<assets-field>
How do you call an asset field from an entry Craft CMS 3?
# How do you call an asset field from an entry Craft CMS 3?

(Asked by: username_0 on 2021-06-07)

I am wracking my brain here trying to understand the new documentation in Craft CMS 3 and the new way it handles assets from an entry. I have a page that creates a list of portfolio entries using thumbnails. The image is placed as a background-image using inline CSS and the div with the content appears on hover. The thumbnails are from a field in my entry called projectThumbnails. This field only allows a single image so pulling an array doesn't make sense, does it?
I got this working using a deprecated method (see code below) but I'd prefer to not have any deprecation warnings on my final site. The warning says "Looping through element queries directly has been deprecated. Use the all() function to fetch the query results before looping over them." but adding .all() to the asset query doesn't seem to fix the issue. Is there a way to avoid creating the asset query and just use the entry query since the field already exists in the entry?

{% block main %}

{# Create entry queries #}
{% set portfolioGrid = craft.entries().section('projects').all() %}
{% set portfolioThumnbnails = craft.assets.volume('projectThumbnails') %}


{# Display the entries #}

    {% for portfolioTile in portfolioGrid %}
    
        
            {{ portfolioTile.projectName }}
            {{ portfolioTile.client.one.title }}
        
    
    {% endfor %}


{% endblock %}

**Tags:** assets-field


---

## 1 answers

### Answer by username_1 on 2021-06-08. Score: 1 | Accepted answer

The documentation on this is a bit scattered about, it took me a while to get the whole picture as well. You need multiple pieces of information:

The documentation on querying assets only mentions craft.assets() as a way to query entries, which you would use to query assets independently of an entry.
Meanwhile, you can find the documentation on how to query assets from an entry field in the Asset Fields documentation. The thing to realize here is that entry.myFieldHandle gives you a craft\elements\db\AssetQuery object, same as craft.assets(), but populated with where-clauses to get only assets selected for that field on that entry.
Finally, you need to look at the documentation for Element Queries, which will give you the different options for executing element queries, including AssetQuery::all(). AssetQuery::one() is the one you're looking for, this will execute the query and return a single result element (or null if no results are found).

Putting it all together, here's how you would access a single thumbnail in your code:
{% set portfolioGrid = craft.entries().section('projects').all() %}
{% for portfolioTile in portfolioGrid %}
    {% set thumbnail = portfolioTile.projectThumbnail.one() %}

    {# AssetQuery::one may return null if the field is empty. #}
    {% if thumbnail %}
        {# Output the thumbnail. #}
    {% endif %}
{% endfor %}

> **Comments:**
> **username_0**: I thought this as well but when I tried this approach I got a twig error, "Variable "projectThumbnail" does not exist." I added "{% set portfolioThumbnail = portfolioTile.projectThumbnail.one() %}" inside the grid for loop and changed the anchor tag to "<a href="{{ portfolioTile.url }}" class="portfolioTile{% if portfolioTile.featuredProject %} featuredProject{% endif %}"{% if projectThumbnail | length %} style="background-image: url('{{ projectThumbnail.getUrl }}'); background-size: cover;"{% endif %}>" to try to grab the thumbnail.  
> **username_1**: @StuartMcCoy You're setting `portfolioThumbnail` but trying to access the variable as `projectThumbnail` :-) If you use the correct variable name it will work! ANother thing: Instead of `{% if projectThumbnail | length %}`, use just `{% if projectThumbnail %}`, since `AssetQuery::one()` returns either a single Asset object or null, not an array.  
> **username_0**: Thanks. It's always something stupid or little that gets overlooked.  

---

