Jaeger
Jaeger

Reputation: 1754

VueJS throws errors because some datas are not ready yet

I'm rather new to VueJS, and I would like to add a picture loaded from an API as a background image. However, the image loading eventually works.

Here is the code:

<template>
    <div id="bio" :style="{ backgroundImage: 'url(' + this.settings.bio_bg.url +')' }">
        <h1>Biography</h1>
        <router-link to="/">Home</router-link><br />
        <span>Biography</span><br />
        <router-link to="/shop">Shop</router-link><br />
        <router-link to="/contact">Contact</router-link><br />
    </div>
</template>

<style scoped>
</style>

<script>
export default {
  data () {
    return {
      settings: {},
      bio: {}
    }
  },
  created () {
      .catch(error => this.setError(error))
    this.$http.secured.get('/settings')
      .then(response => {
        this.settings = response.data
        console.log(this.settings)
      })
      .catch(error => this.setError(error))
  }
}

</script>

The image is loaded, but my console returns two errors:

Error in render: "TypeError: Cannot read property 'url' of undefined"

Cannot read property 'url' of undefined

I guess that since the Axios call is asynchronous, everything arrives after the page is done loading, but is still loaded after.

What would the proper way be to correctly wait for data to be available? I tried a few things that I know from React, but it doesn't load at all (even though the errors stop showing up)

Thank you in advance

Upvotes: 1

Views: 837

Answers (1)

Sergeon
Sergeon

Reputation: 6788

Yo need to be sure that this.settings.bio_bg.url exist from the component birth, so compiler doesn't broke trying to render it. In order to do so, just setup a 'fake' url in the original data of the component:

export default {
  data () {
    return {
      settings: {
        bio_bg: {
          url: '',
        }
      },
      bio: {}
    }
  },
  created () {
    this.$http.secured.get('/settings')
      .then(response => {
        this.settings = response.data
        console.log(this.settings)
      })
      .catch(error => this.setError(error))
  }
}

This not only prevent errors, also provides better intellisense since now your code editor can now that settings has a bio_bg member which in turn has an url.

If instead of ' ', you provide a real image url with a placeholder img, probably the UI will be nicer:

  data () {
    return {
      settings: {
        bio_bg: {
          url: 'http://via.placeholder.com/350x150',
        }
      },
      bio: {}
    }
  }

Upvotes: 3

Related Questions