Ways to refresh the inner component when parent data changes in Vue.js

I've been attempting to retrieve data from an API whenever a value is updated in a parent component, and then utilize it in a child component. Despite my efforts, none of the methods I tried seem to be working.

Below is a simplified version of my components:

Parent

<template lang="html">
<div id="wrapper">
    <h4>My Super Component</h4>
    <button v-on:click="setListID">Load another list</button>
    <ChildComponent :usernames="usernames"></ChildComponent>
</div>
</template>

<script>
import ChildComponent from "./ChildComponent.vue"

export default {
    components: {
        ChildComponent
    },
    data() {
        return {
            listID: 0,
            usernames: undefined,
        }
    },
    watch: {
        listID: function(newID) {
            this.usernames = getUsernames(newID)
        }
    },
    methods: {
        setListID() {
            let id = +prompt("Input the list ID");
            if (Number.isNaN(id)) {
                alert("Please input a valid number");
            } else {
                this.listID = id;
            }
        }
    },
    async mounted() {
        this.usernames = await getUsernames(this.listID)
    }
}

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

// Simulating an API call
async function getUsernames(listID) {
    sleep(200).then(() => {
        switch (listID) {
            case 0:
                return ['Pierre', 'Paul', 'Jaques']
            case 1:
                return ['Riri', 'Fifi', 'Loulou']
            case 2:
                return ['Alex', 'Sam', 'Clover']
            default:
                return []
        }
    })
}
</script>

Child

<template lang="html">
    <p v-for="username in usernames">{{username}}</p>
</template>

<script>
export default {
    props: {
        usernames: Object
    },
}
</script>

The issue I'm facing is that the prop received in the child component is a Promise. Although I attempted to pass an Array, the asynchronous nature of the data fetching function has me stuck as I can't await in the watch.

UPDATE:

I suspect the problem lies within this block of code:

// Simulating an API call
async function getUsernames(listID) {
    await sleep(200).then(() => {
        switch (listID) {
            case 0:
                return ['Pierre', 'Paul', 'Jaques']
            case 1:
                return ['Riri', 'Fifi', 'Loulou']
            case 2:
                return ['Alex', 'Sam', 'Clover']
            default:
                return []
        }
    })
    return 'returned too early'
}

Regardless of the listID provided, the function consistently returns 'returned too early'. Removing this default return results in undefined being returned, which the child component interprets as an array.

Answer №1

Give this snippet a try

Vue.component('Child', {
  template: `
    <div class="">
      <p v-for="username in usernames">{{username}}</p>
    </div>
  `,
  props: {
    usernames: Array
  },
})

new Vue({
  el: '#demo',
  data() {
    return {
      listID: 0,
      usernames: undefined,
    }
  },
  watch: {
    listID: async function(newID) {
      this.usernames = await this.getUsernames(newID)
    }
  },
  methods: {
    setListID() {
      let id = +prompt("Please enter the list ID");
      if (Number.isNaN(id)) {
        alert("Kindly input a valid number");
      } else {
        this.listID = Number(id);
      }
    },
    sleep(ms) {
      return new Promise(resolve => setTimeout(resolve, ms));
    },
    getUsernames(listID) {
      return this.sleep(200).then(() => {
        switch (listID) {
            case 0:
                return ['Tina', 'Max', 'Emma']
            case 1:
                return ['Jack', 'Jill', 'Tom']
            case 2:
                return ['Grace', 'Leo', 'Sophie']
            default:
                return []
        }
      })
    }
  },
  async mounted() {
    this.usernames = await this.getUsernames(this.listID)
  }
})

Vue.config.productionTip = false
Vue.config.devtools = false
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<div id="wrapper">
    <h4>The Amazing Component</h4>
    <button v-on:click="setListID">Load different list</button>
    <Child :usernames="usernames"></ChildComponent>
</div>
</div>

Answer №2

It appears that there is a problem with the props you are sending as an array, but the child component is expecting an object instead. You can try out the code below to potentially resolve this issue:

<template lang="HTML">
  <p v-for="(username, index) in usernames" :key="index">{{username}}</p>

</template>

<script>
export default {
    props: {
        type: Object, // or Array
        default: () => {
          return {} // [] if the type is an array
        }
    },
}
</script>

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

Distinguishing between resolving a promise in a service/factory as opposed to in a controller within AngularJS

After experimenting with resolving a promise in both a service and a controller, I have found that I prefer to resolve it in the service so that I can reuse the variable without having to resolve it multiple times. However, I am encountering an issue where ...

Saving a promise object as a $scope variable in AngularJS: A quick guide

When working with my application, I use Constants.getContants as a promise to retrieve all the necessary constants. I want to store this information in a $scope variable so that it can be easily accessed throughout the controller or application. However, I ...

Issues with navigation drawer not functioning

function adjustMenu() { var navigation = document.getElementById("myTopnav"); if (navigation.className === "topnav") { navigation.className += " responsive"; } else { navigation.className = "topnav"; } } body {margin:0;} ul ...

Sorry, I am unable to fulfill this request as it requests to paraphrase a code snippet

I encountered an issue while trying to run vue.js 3 with vite https://i.sstatic.net/DGHPu.png Prior to this, I had added nodejs into Variable Environments Despite attempting the following solutions, the error persists: Executing npm cache clear & n ...

Using Jquery to set values for css properties

I've recently started using jquery and I have a task related to a drop-down menu that I'm struggling with: if (scrnwidth <= 761) { if (display was block) { //Defaultly testi has display:none property. testi = m ...

What are the steps to integrate and utilize DefinePlugin within your webpack configuration?

Hello, I'm currently trying to implement the DefinePlugin in order to update the version number and ensure that my JavaScript refreshes after a new build is released. Unfortunately, I am encountering issues with getting DefinePlugin to work properly. ...

Unlock the power of AJAX in your WordPress site

I've been exploring the realm of Javascript and AJAX lately. I feel like I'm so close to getting it right, but there's something off with how I'm integrating WordPress ajax functions. I've spent a lot of time going through the docu ...

Guide to creating a search-enabled dropdown menu

Recently, I created a dropdown menu using Bootstrap. The code I used can be found here: http://getbootstrap.com/docs/4.0/components/dropdowns/ <div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownM ...

What type of response does an Ajax request generate when the browser is abruptly closed during the call?

What occurs to the response if an ajax request is sent, but before the server returns a response, the user closes the browser? I am puzzled as to why I receive it in the error callback, considering that the browser has been closed. ...

Performing sequential actions in MySQL and Node.js - What is the best way to achieve this?

Here is the code snippet I am working with: function query1() { var defered = Q.defer(); console.log("In query1"); var connection = mysql.createConnection({ host: '........', user: 'm...c....a.....i', password: '... ...

What is the best way to remove an object from an array in MongoDB?

I am currently using MongoDB and Node.js, but I am facing a small issue when trying to delete an object from an array of objects. Below is the code snippet causing the problem: router.route('/deleteGuestFromJam/:id').delete(function(req, res){ ...

JavaScript for Image Preloading on iOS Devices

Scenario In my project, I have two images called 'car-light.png' and 'car-dark.png'. When a user interacts with the image named car-light.png, it transforms into car-dark.png. Here is the code snippet that represents this functionalit ...

What causes the function execution to not be delayed by setTimeout?

function attemptDownloadingWebsite(link) { iframe = document.getElementById('downloadIFrame'); iframe.src = link; setTimeout(removeFile(link), 25000); } This is the remove file function: function removeFile(link){ $.ajax ...

The expected result is not obtained when making an Ajax request to a PHP variable

I recently encountered an issue with my AJAX GET request. The response I received was unexpected as the PHP variable appeared to be empty. Here is the snippet of jQuery code that I used: jQuery(document).ready(function($) { $.ajax({ url: '/wp ...

Implementing the 'bootstrap tour' feature in a Ruby on Rails application

I have integrated bootstrap-tour.min.css and bootstrap-tour.min.js into my project. <script type="text/javascript" src='bootstrap-tour.min.js'></script> <link rel="stylesheet" type="text/css" href="bootstrap-tour.min.css"> Her ...

Tips for managing image uploads while incorporating pre-set error detection into a form

I'm facing a challenge with integrating an optional image upload feature into my express app. The issue seems to be related to the way I've structured the app, as it appears to be trying to pass the image name from the body instead of utilizing t ...

It appears that req.session is not defined and the user_id within req.session is not

Currently, I am implementing session management with Express and Node using HTTPS. I am facing an issue where I need to create a session in Express for authentication before redirecting to static files in the public folder. Previously, I encountered a prob ...

Dealing with Vue's performance problems when using input type color and v-model

I am encountering a problem with setting the v-model on an input of type color. Whenever I change the color, there is a noticeable drop in frame rate and the application's FPS spikes from 60 to 3. You can see it reflected in the Vue performance graph ...

What is the reason behind console.log() displaying an array, while typeof returning 'object'?

This question pertains to the outcome of a mongoose find() operation. After running the code console.log('apparently this is an ' + typeof campaign.advertGroups, campaign.advertGroups); The resulting output is as follows: apparently this is an ...

The implementation of a generic function interface in Typescript can pose a challenge

I've been working on incorporating a generic function interface, but I'm facing some challenges in getting it to function properly. IToken.ts export interface IToken { token: string; expires: number; } ITokenMapper.ts export interface ...