RESOLVED: I have found a solution that almost solves the issue. By removing
<div v-if="isFrameLoaded">
and binding the source data to <video>
, the video now loads simultaneously with the request being sent. There is no data in getBLOB
, but it still reloads itself, eliminating the need to manually save files. However, I'm still puzzled as to why this specific use of v-if
is not working for me. Thank you for your help!
Edited Frame.vue
// This is necessary
<video v-bind:src="getBLOB">
// Also here
<source v-bind:src="getBLOB" type="video/mp4" />
Your browser does not support the
</video>
EDIT:
state: {
...,
isFrameLoaded: false
}
Getters from the store content.js
getters:{
...,
isFrameLoaded: state => state.isFrameLoaded
}
mutations
mutations: {
...,
SAVE_ISFRAMELOADED(state, boolean) {
state.isFrameLoaded = boolean;
console.log("frame loaded");
},
}
Things I have tried:
binding :key
, this.$forceUpdate()
, <keep-alive>
The problem lies in the fact that
<div v-if="isFrameLoaded">
is being checked before the resource is fully downloaded (isFrameLoaded == false
). At some point later, the resource will be downloaded and the computed property should return true from the $store.getters. However, what I am observing is that the computed property is never called again even after updating its state.
I have implemented similar logic before and it worked as expected. The only notable difference is that Home.vue is a view while Frame.vue is a component where $store works.
This code block does not work in Frame.vue
<template>
...
<div v-if="isFrameLoaded">
<video>
<source v-bind:src="getBLOB" type="video/mp4" />
</video>
</div>
</template>
<script>
export default {
computed: {
isFrameLoaded() {
//this is called just once
console.log("isFrameLoaded()");
return this.$store.getters["content/isFrameLoaded"];
}
}
};
</script>
This piece of code works in Home.vue, where "list" is another component Vue file
<template>
...
<template v-if="childDataLoaded">
<list />
</template>
</template>
<script>
export default {
name: "Home",
computed: {
childDataLoaded() {
return this.$store.getters["content/isThumbnailLoaded"];
}
}
};
</script>
This is where the isFrameLoaded value is modified contentstore.js
getFrameBlob({ commit, state }) {
commit("SAVE_ISFRAMELOADED", false); //HERE
return contentService
.getBigImg()
.then(response => {
var url = URL.createObjectURL(
new Blob([response.data], { type: state.frame.mediaType })
);
commit("SAVE_CURRENTBLOB", url);
commit("SAVE_ISFRAMELOADED", true); //HERE
return url;
});
},
This method updates the condition that works for isThumbnailLoaded
getThumbnails({ commit, state }) {
commit("SAVE_ISTHUMBNAILLOADED", false); //HERE
state.home.imgs.forEach((thumbnail, i) => {
contentService
.getThumbImg()
.then(response => {
var url = URL.createObjectURL(new Blob([response.data]));
commit("SAVE_THUMBFRAME", {
key: state.home.frames[i],
value: url,
like: state.home.likes[i]
});
if (state.thumbFrame.length == state.home.imgs.length) {
commit("SAVE_ISTHUMBNAILLOADED", true); //HERE
}
});
});
return;
I've noticed that removing the v-if statement from Frame.vue solves the issue with image types loading at first try, although video types don't load initially. But oddly enough, updating and saving the project while running it fixes the bug with video resources also loading properly.
So.. Any insights or suggestions? I've read about using the nextTick() function but it seems overly complex for this issue. I'm also curious as to why modifying project files while running it resolves the bug.
Thank you!