0

I want to concatenate a fixed directory path, defined in data, with a file name defined in v-for. When I try to do so with a computed property, I get:

"TypeError: _vm.filePath is not a function".

data: function(){
  return{
    imageDir: '../assets/images/tiles/'
  }
},

computed:{

  filePath: function(fileName){
    let path = this.imageDir + fileName
    return path
  }
}
<image :src="filePath(tile.image)" />

When I move filePath to the methods, it works. However, it was my impression that simple transforms like these are exactly what computed properties are for.

kslstn
  • 1,407
  • 1
  • 14
  • 34
  • `computed`s are similar to data properties but they are just derived (as you have already mentioned). Therefore, they cannot be functions. If you need something that needs to take an input parameter then you are better off using `methods`. Else, you can use some closure magic to make computed return a `function` which you can use in `v-for`. – trk Feb 21 '18 at 09:06
  • I just found this question with the answer that using computed properties in v-for is not possible: https://stackoverflow.com/questions/40322404/vuejs-how-can-i-use-computed-property-with-v-for Thank you for your help, everybody. Can I close this question in favor of the other one? – kslstn Feb 21 '18 at 09:20
  • @kslstn it's not possible only if you don't use components inside `v-for` loop. – oniondomes Feb 21 '18 at 09:53
  • Thank you for pointing that out. Using a child component is actually the elegant solution. I got confused and had the computed property at the parent component level. – kslstn Feb 21 '18 at 09:58

4 Answers4

4

You are getting this error because you treat filePath as a function, but it works as a value. Thus, you don't call it as a function here:

<ChildComponentName :src="filePath(tile.image)" />

If it is computed you do:

<ChildComponentName :src="filePath" />.

To make it work you can try to modify your code like this (assuming you have the access to tile, which you most likely do) if you want it to stay in computed:

computed:{
    filePath(){
        return this.imageDir + this.tile.image;
    }
}

Otherwise, move it to the methods, as Phil mentioned in his answer.

UPD: If you don't have access to this.tile you can calculate full file path inside the ChildComponentName:

computed:{
    filePath(){
        return this.imageDir + this.src;
    }
}

But in such case you would have to have an access to imageDir inside this child component.

oniondomes
  • 2,034
  • 13
  • 22
  • I tried this, but: "TypeError: this.tile is undefined". tile.image refers to the tile in v-for:
  • , so I don't expect it to be accessible inside component's script. Hence my attempt to pass it on as an argument.
  • – kslstn Feb 21 '18 at 09:18
  • Two options: compute `src` inside `ChildComponentName` or move it to the `methods`. – oniondomes Feb 21 '18 at 09:19