title: VueJS: How can I successfully pass arrays from child to parent components
body: <p>I am using the <a href="https://vue-multiselect.js.org/#sub-events" rel="nofollow noreferrer">Vue-Multiselect</a> plugin and trying to emit some data up to a parent component so a backend API can update some records, but I don't know how to do this successfully.</p>
  
  <p>Here's my attempt (and explanation in more detail) with a <a href="https://codesandbox.io/s/multiselect-with-pocs-works3-zl3ff?fontsize=14&amp;hidenavigation=1&amp;module=%2Fsrc%2Fcomponents%2FCustomerPOCSelect.vue&amp;theme=dark" rel="nofollow noreferrer">CodeSandBox Demo</a> <em>Note: To see the multiselect UI in action, go to POST-->ACME WIDGET and click "Edit" where you can mess with the multiselect plugin.</em></p>
  
  <p>In my child component <code>CustomerPOCSelect.vue</code> there is an <code>onRemove</code> event that pushes some data into an array called <code>pocsToRemove</code>. Likewise, there is one for <code>onSelect</code> event that also pushes some data into an array called <code>pocsToAdd</code>.</p>
  
  <p>However, I am unsure how to get from this point to the parent <code>EditPost.vue</code> so I can use the parent's <code>onSubmitUpdate</code>'s event and make the actual update to the server. Every time the user makes a change to the multiselect input (whether they remove or add) and click's the UPDATE POST button, I need to pass the emitted data to the onSubmitUpdate method.</p>
  
  <blockquote>
    <p>EditPost.vue</p>
  </blockquote>
  
  <pre><code>&lt;template&gt;
    &lt;div&gt;
      &lt;label&gt;Point of Contacts:&lt;/label&gt;
      &lt;multiselect
        v-model="value"
        :options="options"
        label="lastname"
        placeholder="plaeholder text"
        track-by="uid"
        :loading="isLoading"
        :custom-label="selectedNameLabel"
        selectLabel
        :multiple="true"
        @remove="onRemove"
        @select="onSelect"
      &gt;
        &lt;template
          slot="singleLabel"
          slot-scope="props"
        &gt;{{ props.option.lastname }}, {{props.option.firstname}}&lt;/template&gt;
        &lt;template slot="option" slot-scope="props"&gt;
          &lt;strong&gt;{{ props.option.lastname }}&lt;/strong&gt;
          , {{ props.option.firstname }} &amp;mdash;
          &lt;small&gt;{{ props.option.email }}&lt;/small&gt;
        &lt;/template&gt;
      &lt;/multiselect&gt;
      &lt;!-- &lt;small id="searchHelpBlock" class="form-text text-muted"&gt;&lt;font-awesome-icon icon="exclamation-circle" /&gt; If customer does not exist, you will be prompted to add a new customer&lt;/small&gt; --&gt;
      &lt;!-- &lt;h3&gt;New contacts to be added:&lt;/h3&gt;
      &lt;ul&gt;
        &lt;li v-for="value in values" :key="value.uid"&gt;{{value.lastname}}, {{value.firstname}}&lt;/li&gt;
      &lt;/ul&gt;--&gt;
    &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  import Multiselect from "vue-multiselect";
  // import ApiService from "@/apiService";
  export default {
    components: { Multiselect },
    props: ["users", "post", "contacts"],
    data() {
      return {
        value: this.contacts,
        options: this.users,
        isLoading: true,
        pocsToRemove: [],
        pocsToAdd: []
      };
    },
    created() {
      this.isLoading = false;
    },
    methods: {
      selectedNameLabel(option) {
        return `${option.lastname}, ${option.firstname} -- ${option.email}`;
      },
      onRemove(option) {
        this.pocsToRemove.push(Number(option.uid));
      },
      onSelect(option) {
        this.pocsToAdd.push(Number(option.uid));
      }
    }
  };
  &lt;/script&gt;
  </code></pre>
  
  <blockquote>
    <p>CustomerPOCSelect.vue</p>
  </blockquote>
  
  <pre><code>&lt;template&gt;
    &lt;div&gt;
      &lt;form @submit.prevent="onSubmitUpdate" v-if="!$route.params.addPost"&gt;
        &lt;h3&gt;Update Post&lt;/h3&gt;
        &lt;div&gt;
          &lt;label for="product_name_input"&gt;Post Name:&lt;/label&gt;
          &lt;br&gt;
          &lt;input type="text" v-model="post.post_name" id="post_name_input" required&gt;
        &lt;/div&gt;
        &lt;br&gt;
        &lt;br&gt;
        &lt;CustomerPOCSelect :users="userProfiles" :post="post" :contacts="contacts"/&gt;
        &lt;br&gt;
        &lt;button type="submit" v-if="!loading"&gt;Update Post&lt;/button&gt;
        &lt;button type="button" disabled v-if="loading"&gt;
          &lt;span role="status" aria-hidden="true"&gt;&lt;/span&gt;
          Updating...
        &lt;/button&gt;
        &lt;button @click.prevent="cancelEdit"&gt;Cancel Edit&lt;/button&gt;
      &lt;/form&gt;
      &lt;form v-if="$route.params.addPost"&gt;
        &lt;h3&gt;Add New Post&lt;/h3&gt;
        &lt;div&gt;
          &lt;label for="product_name_input"&gt;Post Name:&lt;/label&gt;
          &lt;br&gt;
          &lt;input type="text" v-model="post.post_name" id="post_name_input" required&gt;
        &lt;/div&gt;
        &lt;br&gt;
        &lt;button type="submit" v-if="!loading"&gt;Add Post&lt;/button&gt;
        &lt;button type="button" disabled v-if="loading"&gt;
          &lt;span role="status" aria-hidden="true"&gt;&lt;/span&gt;
          Adding...
        &lt;/button&gt;
        &lt;button @click.prevent="cancelEdit"&gt;Cancel Edit&lt;/button&gt;
      &lt;/form&gt;
    &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  import CustomerPOCSelect from "@/components/CustomerPOCSelect.vue";
  export default {
    props: ["id"],
    components: {
      CustomerPOCSelect
    },
    data() {
      return {
        post: {
          post_name: "",
          post_id: null,
          poc_list: []
        },
        posts: [
          {
            post_id: 1,
            process_id: 4,
            post_name: "ACME Widget",
            poc_list: [1, 2]
          },
          {
            post_id: 2,
            process_id: 1,
            post_name: "XYZ Widget",
            poc_list: [3]
          },
          {
            post_id: 3,
            process_id: 2,
            post_name: "ABC Bar",
            poc_list: []
          },
          {
            post_id: 4,
            process_id: 3,
            post_name: "Foo Bar",
            poc_list: [1, 3]
          }
        ],
        userProfiles: [
          {
            uid: "1",
            firstname: "Claiborne",
            lastname: "Heberden",
            email: "cheberden0@gravatar.com"
          },
          {
            uid: "2",
            firstname: "Gerick",
            lastname: "Tetla",
            email: "gtetla1@whitehouse.gov"
          },
          {
            uid: "3",
            firstname: "Raymund",
            lastname: "Espy",
            email: "respy2@freewebs.com"
          },
          {
            uid: "4",
            firstname: "Dilly",
            lastname: "Dimitriev",
            email: "ddimitriev3@skype.com"
          },
          {
            uid: "5",
            firstname: "Roby",
            lastname: "Tabner",
            email: "rtabner4@sohu.com"
          },
          {
            uid: "6",
            firstname: "Jeff",
            lastname: "Smith",
            email: "jsmith@sohu.com"
          },
          {
            uid: "7",
            firstname: "Damn",
            lastname: "Man",
            email: "dman4@sohu.com"
          }
        ],
        loading: false,
        btnDisable: true
      };
    },
    created() {
      this.populateFields();
    },
    methods: {
      populateFields() {
        // this.post.post_id = this.$route.params.addPost
        //   ? null
        //   : this.$route.params.post_id;
        this.post.post_name = this.$route.params.addPost
          ? ""
          : this.$route.params.post_name;
        this.post.poc_list = this.$route.params.addPost
          ? null
          : this.$route.params.poc_list;
      },
      removePOC(x) {
        this.post.poc_list.push(x);
      },
      // onSubmitUpdate() {
      //   this.loading = true
      //   ApiService.updatePost(this.post)
      //     .then(() =&gt; {
      //       this.loading = false
      //       this.$router.push({ path: '/' })
      //     })
      //     .catch(err =&gt; {
      //       if (err.response) {
      //         this.errors = err.response.data
      //       } else {
      //         if (err.request) {
      //           this.errors = err.request
      //         } else {
      //           this.errors = err.message
      //         }
      //       }
      //       this.loading = false
      //       console.error('Error from update', err)
      //     })
      // },
      cancelEdit() {
        this.$router.push({ path: "/posts" });
      }
    },
    computed: {
      contacts() {
        const post = this.posts.find(post =&gt; post.post_id === this.id);
        // all user names
        return this.userProfiles.filter(user =&gt; {
          return post.poc_list &amp;&amp; post.poc_list.includes(Number(user.uid));
        });
      }
    }
  };
  &lt;/script&gt;
  </code></pre>