Vue2: when passing a function as a prop, a warning will be triggered indicating that the prop has

As a newcomer to Vue, I've been enjoying working with Single File Components. Before diving into my main project idea, I decided to experiment with some small components to get a better grasp of the concept.

One such experiment involved creating a component for handling XMLHttpRequests with a progress bar:

https://i.stack.imgur.com/QG15q.png

<template >
  <div  v-if="showQ">
    <div class="text-muted">
      <span>{{humanReadableLead}}</span>
      <span :class="'text-'+color">{{humanReadableMessage}}</span>
      <span>{{humanReadableEnd}}</span>
    </div>
    <div class="progress">
      <div
        class="progress-bar progress-bar-striped progress-bar-animated"
        :class="'bg-'+color"
        role="progressbar"
        :style="{width: String(percent)+'%'}"
        :aria-valuenow="percent"
        aria-valuemin="0"
        aria-valuemax="100"
      ></div>
    </div>

    <div class="text-right text-muted form-text text-small">
      <span class="float-left">{{xhrMessage}}</span>
      <span
        class="badge"
        :class="'badge-'+color"
        data-toggle="tooltip"
        data-placement="right"
        :title="readyStateTooltip"
        >
          {{xhr.readyState}}
        </span>
      <span
        class="badge"
        :class="'badge-'+color"
        data-toggle="tooltip"
        data-placement="right"
        :title="statusTooltip"
      >
        {{xhr.status}}
      </span>
      <span
        v-if="transferComplete"
        @click="goodbye"
        class="badge badge-secondary"
        data-toggle="tooltip"
        data-placement="right"
        title="Dismiss progress bar"
      >
        &times;
      </span>
    </div>
  </div>

</template>

<script>

import {httpStatusCodes, httpReadyStateCodes} from './http-responses';

export default {
  props: {
    method: {
      type: String,
      default: "GET",
      validator: function(value) {
        return ["GET", "POST", "PUT", "DELETE"].includes(value)
      }
    },
    url: {
      type: String,
      required: true
    },
    async: {
      type: Boolean,
      default: true
    },
    success: {
      type: Function,
      default: function() {
        console.log(this.xhr.response)
      }
    },
    readystatechange: {
      type: Function,
      default: function(event) {
      }
    },
    automaticCloseQ: {
      type: Boolean,
      default: false
    }
  },
  data: function() {
    return {
      xhr: new XMLHttpRequest(),
      httpStatusCodes:httpStatusCodes,
      httpReadyStateCodes:httpReadyStateCodes,
      color: "primary",
      percent: 0,
      humanReadableLead: "",
      humanReadableMessage: "",
      humanReadableEnd: "",
      xhrMessage: "",
      showQ: true,
      completeQ: false
    }
  },
  computed: {
    readyStateTooltip: function() {
      var rs = this.xhr.readyState,
      rsc = httpReadyStateCodes[rs]
      return `Ready state ${rs}: ${rsc}`
    },
    statusTooltip: function() {
      var s = this.xhr.status
      // s = s == 0 ? 218 : s
      var sc = httpStatusCodes[s]
      return `Status ${s}: ${sc}`
    },
    transferComplete: function() {
      return this.completeQ
    }
  },
  methods: {
    open: function() {
      this.xhr.open(this.method, this.url, this.async)
    },
    send: function() {
      this.xhr.send()
    },
    goodbye: function() {
      this.showQ = false
    }
  },

  created: function() {
    var that = this
    that.open()

    that.xhr.addEventListener("error", function(event) {
      that.color = "danger"
      that.xhrMessage = "An error has occurred."
    })

    this.xhr.addEventListener("progress", function(event) {
      if (event.lengthComputable) {
        var percentComplete = event.loaded / event.total * 100;
        that.percent = percentComplete
      } else {
        that.percent = 100
        that.xhrMessage = "Unable to compute progress information since the total size is unknown."
      }
    })

    that.xhr.addEventListener("abort", function(event) {
      that.color = "danger"
      that.xhrMessage = "The transfer has been canceled by the user."
    });

    that.xhr.addEventListener("load", function(event) {
      that.color = "success"
      that.xhrMessage = "Transfer complete."
      that.completeQ = true
      if (that.automaticCloseQ) { that.showQ = false }
      that.success()
    })

    that.xhr.addEventListener("readystatechange", function(event) {
      that.readystatechange(event)
    })

    that.send()
  }
}
</script>

<style scoped>
</style>

In your index.html:

<div id="request" style="width:50%;" >
  <http-request :url="'./<some-file>'"/>
</div>

Using JS:

var progress = new Vue({
  el: '#request',
  components: { httpRequest }
})

This setup works quite well, but there are a few minor bugs that have me stumped:

  • I attempted to define a function onSuccess to pass as the success prop, but it resulted in an error from Vue
  • The computed property for statusTooltip does not update as expected
  • Setting automaticCloseQ always defaults to its initial value, regardless of how I try to bind it

For example:

var onSuccess = function() {console.log('here')}

<http-request :url="'./<some-file>'" :success="onSuccess" :automaticCloseQ="true"/>

What could I be missing here?

Answer №1

Thank you for taking the time to read this.

I am facing an issue while trying to define a function onSuccess that I pass to the prop success in Vue. It seems to be throwing an error.

It appears that onSuccess is being defined outside of Vue, when it should actually be defined within Vue's methods


I am having trouble with updating computed properties for statusTooltip.

In Javascript, objects are passed by reference, which means that xhr always points to the same object. This can cause issues with updating computed values. For more information, please refer to https://v2.vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats. One solution could be to create another reactive data called xhrStatus and manually update this status within the xhr's event listeners.


I am struggling to set automaticCloseQ as it keeps reverting to the default value despite my attempts to bind it differently.

(This statement is unclear...)

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

Turn off Appbar padding at the top and bottom

I am looking to create a customized box within the Appbar that spans the full height, as illustrated in the image below: https://i.stack.imgur.com/CFMo0.jpg However, the default Appbar provides padding from all sides to its internal elements, leading to ...

typescript tips for incorporating nested types in inheritance

I currently have a specific data structure. type Deposit { num1: number; num2: number; } type Nice { num: number; deposit: Deposit; } As of now, I am using the Nice type, but I wish to enhance it by adding more fields to its deposit. Ultima ...

Navigating the world of gtag and google_tag_manager: untangling

Tracking custom events in my react application using Google Analytics has been successful. Initially, I followed a helpful document recommending the use of the gtag method over the ga method for logging calls. The implementation through Google Tag Manager ...

The clash between mootools and jQuery

I'm facing an issue with a simple form on a page that loads both Mootools and JQuery. Even though JQuery is in no conflict mode, I am encountering problems. There's a form input named "name"-- <input class="required" id="sendname" name="send ...

Securing AJAX Requests: Encrypting GET and POST Requests in JavaScipt using Node.js

Looking for a way to secure ajax post and get requests using JavaScript. The process would involve: Server generates private and public key upon request Server sends the public key to client Client encrypts data with public key Server decrypts data wit ...

Argument for setInterval function

As a newcomer to programming, I am attempting to develop a basic javascript game. I have encountered an issue with the window.setInterval function and it seems to be causing everything to malfunction. I have been following a tutorial at this link and att ...

Exploring the best practices for loading state from local storage in VueJS/NuxtJS by leveraging the "useLocalStorage" utility

When attempting to utilize useLocalStorage from pinia, I am encountering an issue where the data in the store's state is not fetched from local storage and instead defaults to the default value. Below is the code snippet from my store method: import ...

Saving information from JSON data obtained through the Google People API

My server is connected to the Google People API to receive contact information, and the data object I receive has a specific structure: { connections: [ { resourceName: 'people/c3904925882068251400', etag: '%EgYBAgkLNy4aDQECAwQFBgcICQoLD ...

Smoothly scroll to the bottom of a dynamically updated div using native JavaScript

I am in the process of developing a chat application and my goal is to achieve a smooth scrolling animation that automatically moves the page down to the bottom of the div when dynamic messages are loaded. <ul id="messages"> <li ...

Implementing a custom body class in AngularJS when utilizing partials

Looking for some help with AngularJS. I have an index.html file, along with controllers and partials. The <body> tag is located in the index.html. I am trying to set the class for the body using my controller. After adding a value to $scope.body_c ...

Unique hover tags such as those provided by Thinglink

Looking for a way to replicate the functionality of Thinglink? Imagine a dot on an image that, when hovered over, displays a text box - that's what I'm trying to achieve. I thought about using tooltips in Bootstrap, but I'm not sure if it ...

Using Vue.js: Load component only after user's button click

I need some help with my code setup. I want to make it so that the components "dataPart1' and "dataPart2" are not loaded by default, but only appear when a user presses a button to view the data. How can I achieve this functionality in Vue.js? var ap ...

Efficiently adding values to a variable with the forEach method

I'm encountering an issue with displaying data from a JSON file similar to the one below: Currently, "checked" is set to null. I aim to update it to true within the steps array using a forEach loop. JSON data snippet: { "id": 4, "process": { ...

The function ajax does not recognize response.forEach as a valid function

When I try to use ajax for fetching data from MySQL using PHP and JavaScript, I encounter a function error stating "response.forEach is not a function". Despite looking through various posts on this issue, none of the suggested solutions have been able to ...

When attempting to execute the 'npm start' command, an error was encountered stating "start" script is

Encountering an issue when running "npm start." Other users have addressed similar problems by adjusting the package.json file, so I made modifications on mine: "scripts": { "start": "node app.js" }, However, t ...

The error message received was: "npm encountered an error with code ENOENT while trying to

About a week ago, I globally installed a local package using the command npm i -g path. Everything was working fine until today when I tried to use npm i -g path again and encountered the following error: npm ERR! code ENOENT npm ERR! syscall rename npm ER ...

Checking for undefined values in fields within an array of objects using scenarios in JavaScript

I am encountering an issue with checking for undefined and empty strings in an object array using Javascript. The code provided is partly functional, but I have hit a roadblock. Within the array object, If the field value is undefined or empty, it should ...

Using Angular 2 to access information from the OpenWeather API

Trying to integrate weather data from an openweather API has presented a challenge. The object received contains an array of 40 objects representing the weather forecast for the next 5 days with a 3-hour interval. The issue lies in displaying this 5-day fo ...

Show the helper text when a TextField is selected in Material UI

I would like the error message to only show up when a user clicks on the TextField. Here's my code: import React, { useState, useEffect } from 'react'; import { TextField, Grid, Button } from '@material-ui/core'; const ReplyToComm ...

Tips for sending a Postgres Pool or Client over a socket

After deploying my server to Heroku, I encountered an issue with sending a request to my Raspberry Pi for running a scraping function and updating a table in the Heroku Postgres database. The problem seems to be related to the client.query() function not b ...