Search code examples
javascriptvue.jses6-promise

How to return string from a Promise


Im working on a website with vue where i have to get images with axios from a server and put them as background images of divs. The case is that i have the urls but not all of them are correct. So im trying to make a function that makes an http request and returns me the url if that request is successful.

I thought of something like this:

Template:

<div class="element" :style="bgImg(url)"/>

Script:

methods: {
  bgImg(url) {
    axios.get(url)
      .then(response => {
        return `background-image: url(${response.config.url})`;
      })
      .cath(e) {
        throw new Error(e);
      }
  }
}

I was expecting to get the url returned from that function, but nothing happens.


Solution

  • You could use a custom vue directive for that job:

    Vue.directive('validate-bgimg', function (el, binding) {  
      el.style.backgroundImage = null  // reset 
      var url = binding.value
      if (!url) {
        return
      }
      axios.get(`https://cors-anywhere.herokuapp.com/${url}`)  // get around CORS limitations. Idealy you should call your own api to validate image urls
      .then(response => {
        if (response.status != 200) {
          console.warn("Invalide image url", url, response)
        } else {
          el.style.backgroundImage = `url(${url})`
        }
      })
      .catch(e => {
        console.error("Could not validate image", url, e)
      })
    })
    
    
    new Vue({
      el: "#app",
      data: {
        imgUrl: undefined
      }
    })
    #app {
      background: lightgray;
      border-radius: 4px;
      padding: 20px;
      margin: 20px;
      transition: all 0.2s;
    }
    
    .element {
      margin: 8px 0;
      width: 200px;
      height: 200px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    
    <div id="app">
      <b>test case:</b>
      <button @click="imgUrl='https://dummyimage.com/200x200/000/fff.gif&text=test+1'">1</button>
      <button @click="imgUrl='https://dummyimage.com/200x200/000/fff.gif&text=test+2'">2</button>
      <button @click="imgUrl='https://dummyimage.com/200x200/000/fff.gif&text=test+3'">3</button>
      <button @click="imgUrl='https://httpbin.org/status/404'">HTTP 404</button>
      <button @click="imgUrl='https://httpbin.org/status/503'">HTTP 503</button>
      <button @click="imgUrl='https://invalid.tld'">cannot resolve domain name</button>
      
      <div class="element" v-validate-bgimg="imgUrl"/>
    </div>