0

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 ?

3 Answers 3

2

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>
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. That is exactly what I was looking for. It works.
0

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
  }
}

1 Comment

Combining this with @luigi makes me able to pass data between the two components. Thank you.
0

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
}]

3 Comments

Thanks for your reply. I have changed the prop properties. I have also tried passing the user as you suggested. The user is still not showing. The object is 'undefined'.
I just added some more code to test the object 'undefined'
I made the modifications but on my child component the user is not showing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.