Answers.Body: <p>Your syntax is close, but not quite right and you're setting a variable as a string and later setting it as an Element Model. I think you're searching for something closer to this:</p>
  
  <pre><code>{% macro firstImage(entry) %}
  
      {% if entry.sliderMatrix.total() %}
          {% set block = entry.sliderMatrix.first %}
          {% set image = block.image.first %}
      {% endif %}
  
      {% if image is defined and image %}
          {{ image.url }}
      {% endif %}
  
  {% endmacro %}
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-17T21:14:20.470Z
Answers.Text: This syntax is much better! May I suggest `if image is defined`?
Answers.UserDisplayName: Lindsey D
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-17T21:14:45.300Z
Answers.Text: You surely may :-)
Answers.UserDisplayName: Peter Tell
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-17T22:43:37.140Z
Answers.Text: @Christian if that asset field is not marked as required you should also check if `first()` actually returns an image, so use this conditional `{% if image is defined and image %}`.
Answers.UserDisplayName: carlcs
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-18T08:10:28.863Z
Answers.Text: Even if that asset field **is** marked as required you should still check if `first()` actually returns an image. If that required image is deleted after the entry is created you will end up with an entry with no image.
Answers.UserDisplayName: Marion Newlevant
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-17T21:11:15.543Z
Answers.LastActivityDate: 2015-03-18T11:20:16.780Z
Answers.LastEditDate: 2015-03-18T11:20:16.780Z
Answers.UserDisplayName: Peter Tell
Answers.Body: <p>Hard to say for sure, but here's what I suspect... You may have multiple instances of <code>firstImage</code> being called from your main template.</p>
  
  <p>For some of those instances, <code>entry.sliderMatrix.total</code> is <strong>greater than</strong> zero. For other instances, <code>entry.sliderMatrix.total</code> is <strong>equal to</strong> zero. And of course, when <code>entry.sliderMatrix.total</code> is equal to zero, your <code>if</code> statement will be bypassed.</p>
  
  <p>Realistically, you shouldn't have the <code>image.url</code> call outside of your <code>if</code> statement. Because any time the <code>if</code> statement evaluates to <em>false</em>, then the <code>image</code> variable won't be what you want it to be. In fact, you'll get that exact error, since <code>image</code> will still be set to a string.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-17T21:12:43.477Z
Answers.LastActivityDate: 2015-03-17T21:12:43.477Z
Answers.UserDisplayName: Lindsey D
Body: <p>I've written a short macro to get the first image inside a matrix field.</p>
  
  <pre><code>{% macro firstImage(entry) %}
  
      {% set image = 'hello' %}
  
      {% if entry.sliderMatrix.total() %}
          {% set block = entry.sliderMatrix|first %}
          {% set image = block.image|first %}
      {% endif %}
  
      {{ image.url }}
  
  {% endmacro %}
  </code></pre>
  
  <p>The code throws this error: Impossible to access an attribute ("url") on a string variable ("hello")</p>
  
  <p><code>{{ image.url }}</code> inside the if statement works fine.</p>
  
  <p><code>{{ image }}</code> outside the if statement works too.</p>
  
  <p>Is there anything I don't know or it's even a bug?</p>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2015-03-17T21:10:51.997Z
Comments.Text: The code seems to be alright. Can you detail how your matrix is set up? Maybe a screenshot?
Comments.UserDisplayName: Aaron Berkowitz
Tags: <macro><scope>
Title: Problem with scope in macro
ThreadText: # Problem with scope in macro
  
  (Asked by: username_0 on 2015-03-17)
  
  I've written a short macro to get the first image inside a matrix field.
  
  ```
  {% macro firstImage(entry) %}
  
      {% set image = 'hello' %}
  
      {% if entry.sliderMatrix.total() %}
          {% set block = entry.sliderMatrix|first %}
          {% set image = block.image|first %}
      {% endif %}
  
      {{ image.url }}
  
  {% endmacro %}
  
  ```
  
  The code throws this error: Impossible to access an attribute ("url") on a string variable ("hello")
  
  `{{ image.url }}` inside the if statement works fine.
  
  `{{ image }}` outside the if statement works too.
  
  Is there anything I don't know or it's even a bug?
  
  **Tags:** macro, scope
  
  > **Comments:**
  > **username_1**: The code seems to be alright. Can you detail how your matrix is set up? Maybe a screenshot?  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_2 on 2015-03-17. Score: 2 | Accepted answer
  
  Your syntax is close, but not quite right and you're setting a variable as a string and later setting it as an Element Model. I think you're searching for something closer to this:
  
  ```
  {% macro firstImage(entry) %}
  
      {% if entry.sliderMatrix.total() %}
          {% set block = entry.sliderMatrix.first %}
          {% set image = block.image.first %}
      {% endif %}
  
      {% if image is defined and image %}
          {{ image.url }}
      {% endif %}
  
  {% endmacro %}
  
  ```
  
  > **Comments:**
  > **username_3**: This syntax is much better! May I suggest `if image is defined`?  
  > **username_2**: You surely may :-)  
  > **username_4**: @username_0 if that asset field is not marked as required you should also check if `first()` actually returns an image, so use this conditional `{% if image is defined and image %}`.  
  > **username_5**: Even if that asset field **is** marked as required you should still check if `first()` actually returns an image. If that required image is deleted after the entry is created you will end up with an entry with no image.  
  
  ---
  
  ### Answer by username_3 on 2015-03-17. Score: 3
  
  Hard to say for sure, but here's what I suspect... You may have multiple instances of `firstImage` being called from your main template.
  
  For some of those instances, `entry.sliderMatrix.total` is **greater than** zero. For other instances, `entry.sliderMatrix.total` is **equal to** zero. And of course, when `entry.sliderMatrix.total` is equal to zero, your `if` statement will be bypassed.
  
  Realistically, you shouldn't have the `image.url` call outside of your `if` statement. Because any time the `if` statement evaluates to *false*, then the `image` variable won't be what you want it to be. In fact, you'll get that exact error, since `image` will still be set to a string.
  
  
  ---
  
  