Adwin
Adwin

Reputation: 195

Vuejs Accessing Data in Modal Component Using Props

There are very similar questions to the one am asking but the solutions proposed don't my situation. I am trying to access data from a parent list in a different component using a Modal component in vue. I have tried passing the prop value in the loop as well as the used component in the parent view but receive no data.

This is the parent template.

    <template>
    <table class="table table-bordered table-stripped" v-if="users.length>0">
        <caption>List of Contacts</caption>
        <thead>
            <tr>
                <th scope="col">#</th>
                <th scope="col">Name</th>
                <th scope="col">Action</th>
            </tr>
        </thead>
        <tbody>
            <tr v-for="(user, index) in users" :key="user.id">
                <td>{{index+1}}</td>
                <td>{{user.name}}</td>
                <td>
                    <button type="button" class="btn btn-success btn-sm" @click="initEdit(user)" :euser="user">Edit</button>
                </td>
            </tr>
        </tbody>
    </table>
    <edit-user v-if="showEditUser" :showEditUser.sync="showEdit"></edit-user>
</template>

<script>
import editUser from '@/components/editUser.vue';
export default {
  name: 'listusers',
  components: {
        'edit-user': editUser,
    },
    data() {
      return {
          user: [],
          users: [],
          euser: {},
          showEdit: false,
        };
  },
    methods: {
        initEdit() {
            this.showEditUser = true;
        },
    },
};
</script>

And this is the modal component.

    <template>
        <transition name="modal" role="dialog">
            <div class="modal" style="display: block">
                <div class="modal-dialog" role="document">
                    <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title">Edit Contact</h5>
                    </div>
                    <div class="modal-body">
                        <p>{{euser}}</p>
                        <p>{{euser.id}}</p>
                    </div>
                    <div class="modal-footer">
                            <button type="button" class="btn btn-default" @click="closeModal">Close</button>
                    </div>
                    </div>
                </div>
            </div>
        </transition>
    </template>
<script>

export default {
    name: 'editUser',
    props: {
      euser: {
        type: Object,
      },
      showEdit: {
          'default' : false,
      }
    },
    data() {
        return {
            edit_user: [],
        };
    },
  methods: {
        closeModal(){
            this.$emit('update:showEdit');
        },
  },
};
</script>

I have tried passing the prop value in the loop as shown above as well as in the component shown below.

<edit-user v-if="showEditUser" :showEditUser.sync="showEdit" :euser="user"></edit-user>

How can I get a single user from the parent to display in the modal ?

Upvotes: 0

Views: 6305

Answers (3)

Jalil
Jalil

Reputation: 1246

Just passing the user like this:

<edit-user v-if="showEditUser" :showEditUser.sync="showEdit" :euser="user[indexOfUser]"></edit-user>

And change the prop properties to receive an object an not an Array

  euser: {
    type: Object,
  },

Just try to add in your main component data to user just for testing if the 'undefined' problem comes from there. and in the :euser="user[0]"

user: [{
   id: 1
}]

Upvotes: 0

Shawn Pacarar
Shawn Pacarar

Reputation: 413

First, you must pass the euser prop to the <edit-user/> component not the button that will call the edit.

Second, the initEdit() function should look more like this

initEdit(user) {
  this.user = user
  this.showEditUser = true
}

Third, if you plan on editing the user within the modal you will likely need to create a copy of the user within the child component.

watch: {
  showEditUser() {
    this.editableUser = JSON.parse(JSON.stringify(this.euser))
  }
}

then all of the v-models on the child should point to this.editableUser. when the user goes to save the edit you can emit a new function that could pass the new version back out to the parent like so

saveEdit() {
   this.$emit('save', this.editableUser)
}

you would just need to catch the save in the <edit-user /> component like so

<edit-user v-show="showEditUser" :showEditUSer.sync="showEdit" :euser="user" @save="saveUser" />

//script...data...methods
saveUser(user) {
  let ind = this.users.map(u => u.id).indexOf(user.id)
  if(ind != -1) {
    Object.assign(this.users[ind], user) //put user back where it belongs with new data
  }
}

Upvotes: 0

Luigi
Luigi

Reputation: 314

In your parent component you can create a data property called "currUser:null" and on "initUser" method you can do the following:

initEdit(user){
    this.currUser=user;
    this.showEditUser = true;
}

then your modal component definition will look like the following:

<edit-user v-if="showEditUser" :showEditUser.sync="showEdit" :euser="currUser"> 
</edit-user>

Upvotes: 2

Related Questions