Checking image exists on the server in JS is well described in another SO question - Check if image exists on server using JavaScript?
So it is easy just to choose one of the solutions and integrate it into Vue. Since you want to use it in the v-for
loop, plain function is a bad solution. Better will be to introduce computed
property and extend existing object with some new properties:
Update
Deleted my previous code - computed
is a bad choice either in this case because array/objects returned from computed
prop is not reactive data (changing the content of object returned by computed
will NOT trigger Vue re-render)
New example below shows solution combining deep watching input data (organisation
) + maintaining extended data in the data
part of the component...
const vm = new Vue({
el: '#app',
data() {
return {
// this if external input in question (prop maybe)
organisation: {
owners: [{
employeeId: 100,
name: "Bill",
},
{
employeeId: 200,
name: "Murray",
fail: true // just for demo purposes
},
{
employeeId: 300,
name: "Billy",
},
]
},
ownersWithImage: [],
}
},
methods: {
checkImageExists(owner) {
const img = new Image()
img.onload = () => {
owner.doesImageExist = true
}
img.onerror = () => {
owner.doesImageExist = false
}
img.src = owner.imageUrl
},
extendOwnerWithImage(owner) {
const extendedOwner = {
...owner,
imageUrl: 'https://www.fillmurray.com/250/' + owner.employeeId,
doesImageExist: false // default
}
if (!owner.fail) // just for demo purposes
this.checkImageExists(extendedOwner)
return extendedOwner
}
},
watch: {
'organisation.owners': {
handler: function() {
this.ownersWithImage = this.organisation.owners.map(this.extendOwnerWithImage)
},
immediate: true,
deep: true
}
},
})
.user-profile-image {
width: 150px;
height: 150px;
background-size: cover;
background-position: top center;
border-radius: 50%;
background-color: grey;
text-align: center;
vertical-align: middle;
line-height: 150px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="owner in ownersWithImage" :key="owner.employeeId">
<div v-if="owner.doesImageExist" :style="`background-image:url(${owner.imageUrl})`" class="user-profile-image">
<span>{{ owner.name }}</span>
</div>
<div v-else class="user-profile-image"><span>{{ owner.name }}</span></div>
</div>
</div>