Is there a way to update the parent component when changes occur in the child component?

I have been working on a book tracking application that allows users to keep track of the books they have read or plan to read. The app is built using Vue.js on the front end and Express.js on the server side. It consists of three lists or categories for organizing books. One of the key functionalities I am trying to implement is the ability to change the category of a book (e.g. from 'currently reading' to 'finished') without having to reload the entire page. I have created a 'my books' component that includes a 'book list' component where I pass the 'listType' as a prop to render all three lists. Within the 'book list' component, I use a v-for loop to render all books and utilize a 'book' component for each book object. The 'book' component contains buttons for changing the category of the book. Although I am able to update the listType and database entry on the server side, I am facing difficulty in moving a book from one list to another without refreshing the entire page.

//mybooks component

<template> 
   <BookList listType="current" />
   <BookList listType="wantToRead" />
   <BookList listType="finished" />
</template>

//booklist component

<template> 
    <div v-for="bookElement in bookList" :key="bookElement.id">
      <Book :book="bookElement" />
    </div>
</template>

<script> 
export default {
  data() {
    return {
      bookList: []
    };
  },
  components: {
    Book
  },
  props: ["listType"],
  watch: {
    "$route.query.searchDB": {
      //once a query string search value changes, get list of books from server
      immediate: true,
      async handler(value) {
        const list = (await BooksService.index(value)).data;

        //filter books by categories
        this.bookList = list.filter(element => {
          return element.listType === this.listType;
        });
      }
    }
  }
</script>

// book component

//template to render author, title etc
//and button for example
<button @click="changeTo('current', book.id)">Change to current</button>

<script>
import BooksService from "@/services/BooksService";
export default {
  data() {
    return {
      isCurrent: false,
      isLater: false,
      isFinished: false
    };
  },
  props: ["book"],
  mounted() {
    if (this.book.listType === "current") {
      this.isCurrent = true;
    } else if (this.book.listType === "finished") {
      this.isFinished = true;
    } else this.isLater = true;
  },
  methods: {

    async changeTo(list) {
      this.book.listType = list;

      try {
        await BooksService.put(this.book);
      } catch (err) {
        this.error = err;
      }      
    }
  }
};
</script>

Answer №1

You're heading in the right direction, but you need to better grasp how Vue handles data.

What you're getting right

Your parent component booklist is correctly passing data to the child component Book using the prop binding :book.

Next steps

When a change occurs in the Book component, it should emit an event using $emit('bookChanged', book) so that any parent components are informed of the change and can react accordingly. In this example, your code should look like this:

<Book :book="bookElement" @bookChanged="RefreshMe_Method"  />

At this point, the RefreshMe_Method can update the data passed to the prop

:book</code, or alternatively force a update using <code>this.$forceUpdate();
, although updating the data should suffice.

Handling data flow

  1. A Parent component shares data with its child (like a school lunch on the first day).
  2. The Child component displays and potentially changes the data (using a local copy, not directly modifying the prop), or performs specialized actions (such as discarding vegetables).
  3. The child emits an event to notify others of the change.
  4. All parent components can respond accordingly from this point onward (like grounding the child or only packing broccoli in the lunch).

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

Implementing Content-Security-Policy for a web application embedded in an iframe

Hey there! I've got this cool webapp called myApp, developed using Spring Boot and Vaadin. It's going to be deployed on a Tomcat server at http://tomcatserver:8080/myApp Now, what I want to do is display the webapp in an iframe like this: <if ...

Can I simultaneously utilize submit and ajax functions?

As I work on CRUD for our website, the approach we are taking involves using submit. However, there are occasions where I need to pass data from a JS file to my controller (I am using Codeigniter). I am now considering whether it is common practice to do ...

Comparing scrollIntoView and moveToElement functions

When working with Selenium WebDriver, there are two primary methods to ensure an element is within the visible area: Scrolling into view: ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element); Using moveToElemen ...

accessing the angular fullstack default application by authenticating via google oauth2

Currently, I have my angular fullstack application running on localhost:9000. I am trying to implement a feature that allows users to log in by clicking the "Connect with Google+" button on the login page. However, I keep encountering an error 400 with th ...

Creating a default homepage across various HTML files using Google Apps Script and deploying it as a WebApp

Is there a way to set a default main page on multiple HTML and GS files in Google AppScript? I plan to publish it as a Web App. Have you attempted using the doGet function? ...

I am experiencing an issue where the Axios configuration does not display the OnUploadProgress on my response

I have been attempting to track the progress of file uploads from the front end, but I am encountering an issue where the onUploadProgress is not being received in the configuration catch. This problem arises as I am relatively new to using Axios. axios({ ...

Is there a more efficient method for writing my jQuery code that follows a step-by-step approach?

I have developed a step-by-step setup process that guides users through various sections. Instead of using separate pages for each step (like step1.php, step2.php, etc.), I have all the code contained in one page named setup.php. This is achieved by utiliz ...

Struggling to set up Tailwind in NuxtJS configuration

Using the "@nuxtjs/tailwindcss": "^2.0.0" for my Nuxt App has been quite helpful. Upon installation, it generated a tailwind.config.js file. I made some modifications to the code below: module.exports = { theme: {}, variants: {}, plug ...

Tips on customizing the appearance of the dropdown calendar for the ngx-daterangepicker-material package

Is there a way to customize the top, left, and width styling of the calendar? I'm struggling to find the right approach. I've been working with this date range picker. Despite trying to add classes and styles, I can't seem to update the app ...

What is the best way to configure maxSockets in Node.js while working with Express?

Can the maximum number of sockets in Node.js be adjusted while working with the Express framework? More information can be found here. ...

Utilize utility functions within the onCreated lifecycle event in Meteor

Here is my current setup: Template.myTemplate.helpers({ reactiveVar: new ReactiveVar }); How can I initialize reactiveVar within the onCreated function? Template.restaurantEdit.onCreated(function() { // I want to initialize helpers.reactiveVar here ...

Issue encountered with dynamic localizations in Vue-i18n when fetching from an HTTP request

My goal is to load localization dynamically through an HTTP call rather than packaging it with the application for better management. However, I encountered an issue where the language does not load on initial render but updates properly when changing rout ...

What is the best way to avoid having multiple files in a JavaScript file input when a user selects a new file?

I am trying to implement a file input using vanilla JavaScript, and my goal is to restrict the user to uploading only a single file at a time. The issue I am facing is that if the user repeatedly selects a file and clicks the upload button, the file gets ...

Code-based document editing with CouchBase

To test Couchbase, I need to create a servlet that will edit 1,000 JSON documents by changing the value of '"flag": false' to '"flag": true'. How can I achieve this task? Here is my view code for finding documents with '"flag": fa ...

What is the best way to update the text on buttons once they've been clicked for a variety of buttons

I'm encountering an issue with multiple buttons where clicking on any button causes the text to change on the first button, rather than the one I actually clicked on. All buttons have the same id, and using different ids for each button seems impracti ...

Compiling TypeScript to JavaScript with Intellij IDEA while preserving the folder hierarchy

Seeking assistance with maintaining directory structure when compiling Typescript to Javascript in Intellij Idea. The current directory setup is as follows: root - ts - SomeClass1.ts - SomeFolder - AwesomeClass2.ts - tsc The desired compiled file ...

Heads up in vue-router 3.5.1: Starting with Vue Router 4, the v-slot API will automatically enclose its content within an <a> tag

When utilizing "vue": "^2.6.12" and "vue-router": "^3.5.1", I am encountering a warning message every time the page reloads: [vue-router] In Vue Router 4, the v-slot API will by default wrap its content with an &l ...

Struggling to navigate the DOM using JavaScript and looking for guidance?

I have been searching for an answer to this question without any luck. I am wondering if someone can assist me with finding a solution... I need help using JavaScript (not jQuery) to retrieve the class of the following li element when searching for ' ...

Withdrawal of answer from AJAX request

Is there a way to create a function that specifically removes the response from an AJAX call that is added to the inner HTML of an ID? function remove_chat_response(name){ var name = name; $.ajax({ type: 'post', url: 'removechat.php ...

Is there a way to extract a particular value from a JSON URL and transfer it to a JavaScript variable?

I am looking to extract current exchange rates from a JSON URL for implementation in a webpage. Specifically, I want to retrieve a particular exchange rate (such as the US Dollar) and store it in a variable for use within a JavaScript function. Below is a ...