0

I have an image that i am binding the source to pull in dynamic data:

 <img :src="'/public/images/' + media.client.name + '_' + media.client.id + '/' + media.type + '/' + media.fileName + '.' + media.ext " alt >

The media.client.name returns a string that has %20 instead of spaces.

I have created a filter:

removeSpecial(value) {
  return value.replace("%20", " ");
}

How can I use this filter in the data binding of source please?

I have tried:

 <img :src="'/public/images/' + media.client.name | removeSpecial + '_' + media.client.id + '/' + media.type + '/' + media.fileName + '.' + media.ext " alt >

and

 <img :src="'/public/images/' + {{ media.client.name | removeSpecial }} + '_' + media.client.id + '/' + media.type + '/' + media.fileName + '.' + media.ext " alt >

Neither seem to work unfortunately.

1
  • Filters are not supported in attribute binding anymore. With that said, use decodeURIComponent instead of find and replace. And for the specific purpose, instead of building url in line inside the binding expression, consider using a computed property. Commented Jan 22, 2019 at 12:08

2 Answers 2

2

You can make method which will return prepared url computed method like this:

imageUrl(media){
  return '/public/images/' + media.client.name.replace("%20", " ") + '_' + media.client.id + '/' + media.type + '/' + media.fileName + '.' + media.ext;
}

Or if media is assigned in data you can use computed method which will return you same url

computed: {
 imageUrl(){
  return '/public/images/' + this.media.client.name.replace("%20", " ") + '_' + this.media.client.id + '/' + this.media.type + '/' + this.media.fileName + '.' + media.ext;
 }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you ever so much! This is great and a learning curve for me.
1

That would depend on how you want to decode the URI component. If this media data is populated dynamically (I suppose so), you could make a method for parsing and decoding it (see example below). If you need this decoder as a filter, however, here's an excerpt from the docs:

Filters should be appended to the end of the JavaScript expression, denoted by the "pipe" symbol.

So your best bet is probably to use a computed property so you can "pipe" it. And yes, you could utilize the native method decodeURIComponent() for this exact purpose.

Approach #1: Method only

new Vue({
  el: '#app',

  data() {
    return {
      rootPath: '/public/images/',

      media: {
        client: {
          name: 'Music%20file%20with%20spaces',
          id: 123
        },
        type: 'music-file',
        fileName: 'some_music',
        ext: 'mp3'
      }
    }
  },

  methods: {
    getImgSource(media) {
      // Destructures the properties for improved readability.
      const { client, type, fileName, ext } = media;
      const { name, id } = client;
      
      // Uses template literals. Particularly useful for this situation
      // where you have several, unique delimiters.
      // Helps you see clearer how each of these URI components is combined.
      return `${this.rootPath}${decodeURIComponent(name)}_${id}/${type}/${fileName}.${ext}`;
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <!-- Commented out for demo purposes, because I don't have the file.
  <img :src="getImgSource(media)" :alt="media.fileName" /> -->
  
  <!-- Let's assume this is an image element -->
  <div v-text="getImgSource(media)"></div>
</div>

Approach #2: Computed property + filter

new Vue({
  el: '#app',

  data() {
    return {
      rootPath: '/public/images/',

      media: {
        client: {
          name: 'Music%20file%20with%20spaces',
          id: 123
        },
        type: 'music-file',
        fileName: 'some_music',
        ext: 'mp3'
      }
    }
  },

  computed: {
    mediaFile() {
      const { client, type, fileName, ext } = this.media;
      const { name, id } = client;
      
      return `${this.rootPath}${name}_${id}/${type}/${fileName}.${ext}`;
    }
  },
  
  filters: {
    decodeName: window.decodeURIComponent
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <!-- Let's assume this is an image element -->
  <div>{{ mediaFile | decodeName }}</div>
</div>

Hope that helps.

2 Comments

This is great. Thank you ever so much! This solution has worked in my project!
Glad it helped! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.