1

I was trying to implement watcher like in the following solution: How to listen for 'props' changes

and I have an attribute called "selectedItem" which I'm trying to pass on to a child and watch over the value that comes so I can make some manipulations on it over the handler, but the watch isn't being triggered for some reason.

here are the parent and child code:

parent (Products component):

<template>
  <div class="container">
    <Popup item="selectedItem" />

    <b-table striped hover :items="products" :fields="fields">
      <template #cell(Edit)="data">
        <b-button
          v-b-modal="'edit-modal'"
          v-on:click="setSelectedItem(data.item)"
          variant="warning"
        >
          Edit
        </b-button>
      </template>
    </b-table>
  </div>
</template>

<script>
import Popup from "./Popup";

export default {
  name: "Products",
  components: { Popup },
  data() {
    return {
      products: [],
      countries: [],
      fields: [],
      selectedItem: null,
    };
  },
  methods: {
    getProducts() {
      fetch("http://localhost:5000/", {
        method: "GET",
        headers: {
          "Content-Type": "application/json",
          Accept: "application/json",
        },
      })
        .then(async (res) => {
          try {
            let data = await res.json();
            this.products = data.products;
            this.countries = data.countries;
            this.fields = Object.keys(this.products[0]);
            this.fields.push({ key: "Edit", label: "Click & Edit" });
            console.log(this.fields);
          } catch (error) {
            console.log(error);
          }
        })
        .catch((error) => console.log(error));
    },
    setSelectedItem(item) {
      this.selectedItem = item;
    },
  },
  watch: {
    selectedItem: {
      handler(val) {
        console.log(val);
      },
      deep: true,
    },
  },
  created() {
    this.getProducts();
  },
};
</script>

child (popup component)

<template>
  <b-modal id="edit-modal">
    <!-- <b-button v-on:click="updateItem">update</b-button> -->
  </b-modal>
</template>

<script>
export default {
  name: "Popup",
  props: {
    selectedItem: Object,
  },
  data() {
    return {
      item: undefined
    };
  },
  watch: {
    selectedItem: {
      handler(val) {
        console.log(val);
      },
      deep: true,
    },
  },
};
</script>

I know I've asked a question which runs a lot here, but haven't figured what I did wrong.

ishaishai
  • 73
  • 9

1 Answers1

2

Your Popup component is declaring it receives prop with the name selectedItem. But you are using the Popup like <Popup item="selectedItem" /> which means that you are trying to pass a string "selectedItem" into a prop called item

This is what you want:

<Popup :selectedItem="selectedItem" />
Michal Levý
  • 33,064
  • 4
  • 68
  • 86
  • Thanks friend. I forgot about the string template, and didnt realize that I've used different names for the prop. silly me. – ishaishai Jul 23 '21 at 13:31