Display or conceal a vue-strap spinner within a parent or child component

To ensure the spinner appears before a component mounts and hides after an AJAX request is complete, I am utilizing the yuche/vue-strap spinner. This spinner is positioned in the parent days.vue template immediately preceding the cycles.vue template.

The structure of the days.vue template is as follows:

<template>
    <accordion :one-at-a-time="true" type="info">
        <panel :is-open="index === 0" type="primary" :header="'Day ' + day.day" v-for="(day, index) in days" :key="day.id">
            <accordion :one-at-a-time="true" type="success">
                <panel is-open type="success" header="Cycles">
                    <spinner :ref="'cycles_spinner_' + day.id" size="xl" text="Loading cycles..."></spinner>
                    <cycles
                        :day="day"
                    >
                    </cycles>
                </panel>
            </accordion>
        </panel>
    </accordion>
</template>

<script>
export default {
props: [
'plan'
],
data() {
return {
days: {}
}
},
beforeMount: function () {
var self = this;

axios.get('/plans/' + this.plan.id + '/days/data')
.then(function (response) {
self.days = response.data;
})
.catch(function (error) {
console.log(error);
});
}
}
</script>

The content of the cycles.vue template is shown below:

<template>
    <accordion :one-at-a-time="true" type="info">
        <panel :is-open="index === 0" type="primary" :header="'Week ' + cycle.week + ': ' + cycle.name" v-for="(cycle, index) in cycles" :key="cycle.id">
            <form v-on:submit.prevent="update">
                ....misc input fields here...
            </form>
        </panel>
    </accordion>
</template>

<script>
export default {
props: [
'day'
],
data() {
return {
cycles: []
}
},
beforeMount: function () {
var self = this;

this.$parent.$refs['cycles_spinner_' + this.day.id].show();

axios.get('/plans/days/' + this.day.id + '/cycles/data')
.then(function (response) {
self.cycles = response.data;
this.$parent.$refs['cycles_spinner_' + this.day.id].hide();
})
.catch(function (error) {
console.log(error);
});
}
}
</script>

Attempting to use

this.$parent.$refs['cycles_spinner_' + this.day.id].show();
results in the error message
Cannot read property 'show' of undefined
.

A similar error occurs when using

this.$refs['cycles_spinner_' + this.day.id].show();
. Is there a more efficient method than what I am currently employing?

Answer №1

refs within v-for loops create arrays. As stated in the documentation (emphasis added):

When using ref with v-for, the obtained reference will be an array containing child components that correspond to the data source.

So instead of:

this.$parent.$refs['cycles_spinner_' + this.day.id].show();

You should use:

this.$parent.$refs['cycles_spinner_' + this.day.id][0].show();

The index is 0 because you are creating only one reference named 'cycles_spinner_' + this.day.id per iteration.


Same Issue Arises Within Axios Promises (Be cautious with this)

In your axios .then() block, you will encounter a similar challenge. Additionally, avoid using this inside .then(function(response) {; opt for self instead:

axios.get('/plans/days/' + this.day.id + '/cycles/data')
  .then(function(response) {
    self.cycles = response.data;
    self.$parent.$refs['cycles_spinner_' + this.day.id][0].hide();
//  ^^^^---------------- changed ----------------------^^^
  })
  .catch(function(error) {
    console.log(error);
  });

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

Using ThreeJS to load and display several meshes from a .json 3D file

I downloaded a .json file from an online 3D editor and now I'm facing an issue while trying to load and create 20 instances of it, similar to this example. Sadly, my code seems to be flawed as all 20 instances are behaving as if they are the same obje ...

What is the best way to send the image location to a child component in Vue?

Having trouble displaying my image for some reason. I have the image path sent to the component for rendering, but it just won't show up. I am using Vue-CLI for this project. This is how my folders are structured: src | App.vue | bulbasaur.png | / ...

What is special about this element, textarea?

Hey there, I've got this JavaScript code that currently works on all textarea elements on the site. However, I'd like it to only work on one specific element. function limits(obj, limit) { var text = $(obj).val(); var str_length = $(obj) ...

Using JavaScript to Apply CSS Styles in JSF?

Is it possible to dynamically apply a CSS style to a JSF component or div using Javascript? I have been searching without any success. Below is some pseudo code: <div style="myJSStyleFunction("#{myBean.value}")"> stuff </div> The function wo ...

Navigate to a unique component

I am attempting to navigate to the location of a custom component, but the reference to it is not returning a valid HTML node. The function "goToContactUs" should execute this action. What would be the most effective approach to accomplish this? class H ...

What is the best way to send these values to a JavaScript function and show them one by one on an HTML webpage?

There are 100 values stored in the database. https://i.stack.imgur.com/584Op.jpg I need to retrieve these values from the database using PHP and pass them to JavaScript using Ajax. PHP CODE: for($i=0;$i<=9;$i++) { $random = (10 * $i) + rand(1,10); ...

How can we define a method in Vue.js similar to Handlebars.registerHelper?

Transitioning from "Handlebarjs" to "Vuejs", I am looking to define a method that can be used in multiple sections of my code. Similar to Handlebars.registerHelper(); Any assistance would be greatly appreciated. ...

Receive information from the server and display it on the front-end

Hello! I'm currently in the process of developing a video uploader for my website. So far, I've successfully been able to upload videos from the front-end (built with React.js) to the back-end public folder (using Node.js) through the POST method ...

Utilize Vue.js methods to reverse the string within a paragraph using the appropriate function

Hello everyone, I've been attempting to implement a function to reverse a string within a paragraph text in vue.js. I've created a method called reverseword to reverse the words and added it to a card using :rule="reverseword()", but un ...

What is the reason behind the cross-origin error thrown by JSON.parse?

When I don't use JSON.parse, my code works perfectly fine. However, as soon as I attempt to parse or stringify my data object, a cross-origin error is thrown. Why is this occurring and what steps can I take to resolve it? The snippet of code in Title ...

What is the method for concatenating two strings in JavaScript without any whitespace in between?

When working with two strings involving time, consider the following scenario: var gettime= $("#select-choice-2 :selected").text(); The above code returns a time value in 24-hour format, such as 17:45 However, if you require the time to display in the ...

How can I retrieve a large API response in Nuxt without causing the page to render slowly?

I have a dynamic page in my Nuxt project where I utilize Fetch and Axios to retrieve all the necessary data, such as photos and text. The issue I'm facing is that the API response is quite long, with more than 3800 lines of code. When loading the pa ...

Display a div element with Angular's ng-show directive

I am encountering difficulties with implementing ng-show and $pristine. Below is the code snippet (also available on CodePen): <blockquote ng-show="!comment.author.$pristine && !comment.rating.$pristine && !comment.comment.$pristine"&g ...

Is there a way to adjust the dimensions of Google charts within a Bootstrap tab for a more customized appearance?

I've been working on a page that features tab navigation using Twitter Bootstrap and I want to include Google charts within each tab's content. However, I've encountered an issue where the charts are appearing in different sizes despite spec ...

Add the text received from the Ajax request to an array specifically designed for AmCharts

Hello, I'm new to JavaScript and seeking assistance. My goal is to create a chart with real-time data from my MCU, but I'm unsure about pushing a string into an array. Currently, the Array (chart.dataProvider) in this code remains undefined. var ...

The time-out counter fails to detect the input field

After writing a method to reset the timeout on mouse click, keyup, and keypress events, I realized that it does not account for input fields. This means that when I am actively typing in a field, the timeout will still occur. Below is the code snippet: ...

Calculating minutes per hour during a specific date range using JavaScript

What is the method to create an array representing minute counts per hour within a specified date range? If we have the following dates: const initial = new Date('2019-04-04 12:14'); const final = new Date('2019-04-04 16:21'); How ca ...

The localStorage API (getItem/setItem) is not supported with setTimeout

I find it fascinating how these two codes exhibit different behaviors. It's interesting to note that functions like 'console.log' would work in both scenarios, but localStorage API functions such as getItem and setItem do not. setTimeout(()= ...

Validate input JQuery only when specific radio buttons are chosen

My form currently has basic validation set up like this: <script type="text/javascript"> $(function() { $("#postform").validate({ rules: { ...

Steps to restrict input in a text area to only backspace and cursor movements

I'm in search of a jQuery function that restricts movements to only arrow keys and backspace within a textarea. However, there seems to be an issue with the arrow key movements not functioning correctly. function moveArrow(e){ if(e.which >= 3 ...