Computed property not properly updating the v-if condition

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!

Answer №1

It is unnecessary to create computed properties as store getters are already reactive.

The approach of wrapping the getter in a computed property does not make the computed property reactive. Getters, just like computed properties, are actually methods that are implicitly executed when referenced. If you log the computed property:

console.log('Getter: ', this.$store.getters["content/isThumbnailLoaded"]);

You will notice that it logs a method instead of the expected value.

To map your getter to computed properties in your component, you can use mapGetters:

import { mapGetters } from 'vuex';

  export default {
    computed: {
      ...mapGetters({
        isFrameLoaded: 'content/isFrameLoaded',
      }),
    }
  };

If you prefer the previous approach, you can modify it like this:

export default {
  computed: {
    isFrameLoaded() {
      console.log("isFrameLoaded: ", this.$store.getters["content/isFrameLoaded"]());
      return this.$store.getters["content/isFrameLoaded"]();
    }
  }
};

I recommend using the first method as it is more readable and cleaner.

Best regards.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Incorporating a JavaScript variable into an inline HTML onclick event

Having trouble passing a variable into an inline onclick function. I've tried researching and following suggestions from this link, but encountered errors (Uncaught SyntaxError: missing ) after argument list): pass string parameter in an onclick func ...

Component loader with dynamic rendering for multiple components

Currently, I am in search of a method to dynamically render components within my Angular application. While exploring various options, I came across the concept of dynamic component loading in Angular (refer to https://angular.io/guide/dynamic-component-lo ...

Scriptmanager and Rokbox clash in a heated confrontation

I'm having trouble getting RokBox to display images on my webpage because the asp:ScriptManager seems to be causing some issues. After trying to troubleshoot, I found that when I remove the following code: <asp:ScriptManager ID="ScriptManager1" r ...

window.print function appears multiple times

Looking for help with a sample script I have that prints a section of my website page when a button is clicked. The issue arises when using ajax to transition and clicking the same button results in window.print activating multiple times. How can I ensur ...

What is the best way to retrieve all collections and their respective documents in Firestore using cloud functions?

Seeking to retrieve an array structured as [1year, 1month, etc] with each containing arrays of documents. Currently encountering a challenge where the returned array is empty despite correct snapshot sizes. Unsure if issue lies with push() method implemen ...

What are some tips for incorporating Google Maps v3 with Twitter Bootstrap?

I'm looking to incorporate Twitter Bootstrap's Tabbed Menus into a Google Maps project that is currently coded entirely in javascript. The issue I'm facing is that since Twitter relies on jQuery, I'm unsure of how to effectively utilize ...

Add HTML to a div element using jQuery when content is replicated through JavaScript

I have encountered an issue while appending HTML from a dynamically created div using JavaScript. The problem arises when I try to append the HTML multiple times - each time it adds the content twice, thrice, and so on. This is possibly happening because i ...

Utilize the filtering feature within the Vue select module

I'm struggling to get the select filter to work properly in my Quasar application. When I open the select, there is no list displayed and no value gets selected. Can someone help me understand why it's not working? <q-select v-mo ...

Sort through the JSON data and showcase it in a gridded format

I need assistance with displaying data from a JSON object in a grid based on user selections. The user should be able to select a year and make from a dropdown menu, and the corresponding data should then be filtered and displayed in a grid. For example, i ...

Ways to postpone a for loop in Jquery

Currently, I am working on creating an image gallery using a for loop to load all the images. However, I am facing an issue where the loop is running too fast, and I would like to add a delay after each iteration. I attempted to use a timeout function, bu ...

Using various functions for event listeners

Avoiding jQuery Hello there! I'm currently working on implementing multiple Event Listeners for a button. function logoContame(){ var logo = document.getElementById("logoheader"); logo.addEventListener("click", hideDivHistorias) ...

The dependency path in the package.json file contains all the necessary files

I recently developed a JavaScript package and here is the configuration in my package.json: { "name": "packageName", "version": "1.0.0", "description": "Description of the package", " ...

html2canvas encountered a CORS error when trying to retrieve images from an external domain

I have been attempting to export a react component as a PDF file. Here are the steps I have followed: Converting the component into an image using html2canvas Creating a PDF document Attaching the image to the PDF The component contains images with URLs ...

Create a personalized edit button for ContentTools with a unique design

I'm struggling to figure out how to customize the appearance and location of the edit button in ContentTools, a wysiwyg editor. After some research, I learned that I can use editor.start(); and editor.stop(); to trigger page editing. However, I want ...

The popup is unable to remain in the center of the screen because the background page keeps scrolling back to the top

Whenever I click a button to open a popup window, the page unexpectedly scrolls to the top. It's frustrating because if I'm at the bottom of the page and press the 'submit' button, the popup doesn't display in the center as intende ...

Having trouble getting DeviceOrientationControls to function properly

For the past week, I've been attempting to use my smartphone's orientation controls to manipulate my three.js scene. Although I lost the tutorial that originally guided me, I managed to find the example I saved from it. However, despite studying ...

Comparing a stored array in Mongo against a native JavaScript array with identical length and values results in a failed deep assert comparison

In my mongoose ORM, I have a field in mongo defined as: state: {type: [Number], required: true } When I check a sample document in the mongo console, the state appears as: state: [ 1, 1, 1 ] Everything seems to be in order so far. However, when I try t ...

What are the methods for choosing various boxes using the UP/DOWN/RIGHT/LEFT arrow keys?

This code snippet displays a 3x3 matrix where boxes can be hovered over and selected. The goal is to navigate around with keys and select boxes using ENTER. Can anyone provide guidance on how to achieve this functionality? <link rel="stylesheet" href ...

Is there a way to display the back and forward buttons on a popup window opened through window.open or self.open in Chrome browser?

When I try to open a popup window using the code snippet below, I am facing some issues. self.open('myJSPPage','ServicePopUp','height=600,width=800,resizable=yes,scrollbars=yes,toolbar=yes,menubar=yes,location=yes'); Afte ...

Input ENTER triggered JSON path loading

Upon clicking "enter", I am looking to display the description corresponding to the title. To achieve this, I have defined a variable to store the path of the description: var descri = json.query.results.channel.item.map(function (item) { return item. ...