CopyPastor

Detecting plagiarism made easy.

Score: 1; Reported for: Exact paragraph match Open both answers

Possible Plagiarism

Reposted on 2021-06-07
by Hiws

Original Post

Original - Posted on 2019-09-17
by Hiws



            
Present in both answers; Present only in the new answer; Present only in the old answer;

The issue with your code is because of a Vue 2 caveat. Adding properties to objects after they've been added to `data` will *not* be reactive. You can read more about that [here](https://vuejs.org/v2/guide/reactivity.html#For-Objects).
Now, calling a function like you are doing in the template seems like bad practice. You should instead do it after fetching your data, or use something like a computed property to do your mapping.
Here's two simplified examples.
### Mapping after API call ```js { data() { return { items: [], showRows: [] } }, methods: { async fetchData() { const { data } = await axios.get('https://example.api') foreach(item of data) { const isRowExpanded = this.showRows.includes(item.id); item._rowDetails = isRowExpanded; } this.items = data; } } } ```

### Using a computed ```js { computed: { // Use `computedItems` in `<b-table :items="computedItems">` computedItems() { const { items, showRows } = this; return items.map(item => ({ ...item, _showDetails: .showRows.includes(item.id) })) } }, data() { return { items: [], showRows: [] } }, methods: { async fetchData() { const { data } = await axios.get('https://example.api') this.items = data; } } } ```
For a more complete example, check the snippet below.
<!-- begin snippet: js hide: true console: false babel: false -->
<!-- language: lang-js -->
const { name, datatype, image } = faker;
const getUser = () => ({ uuid: datatype.uuid(), personal_info: { first_name: name.firstName(), last_name: name.lastName(), gender: name.gender(), age: Math.ceil(Math.random() * 75) + 15 }, avatar: image.avatar() });
const users = new Array(10).fill().map(getUser);
new Vue({ el: "#app", computed: { computed_users() { const { expanded_rows, users } = this; return users.map((user) => ({ ...user, _showDetails: expanded_rows[user.uuid] })); }, total_rows() { const { computed_users } = this; return computed_users.length; } }, created() { this.users = users;
setInterval(() => { users.push(getUser()); this.users = [...users]; }, 5000); }, data() { return { per_page: 5, current_page: 1, users: [], fields: [{ key: "avatar", class: "text-center" }, { key: "name", thClass: "text-center" }, { key: "personal_info.gender", label: "Gender", thClass: "text-center" }, { key: "personal_info.age", label: "Age", class: "text-center" } ], expanded_rows: {} }; }, methods: { onRowClicked(item) { const { expanded_rows } = this; const { uuid } = item;
this.$set(expanded_rows, uuid, !expanded_rows[uuid]); } } });
<!-- language: lang-html -->
<link href="https://unpkg.com/bootstrap@4.5.3/dist/css/bootstrap.min.css" rel="stylesheet" /> <link href="https://unpkg.com/bootstrap-vue@2.21.2/dist/bootstrap-vue.css" rel="stylesheet" />
<script src="https://unpkg.com/vue@2.6.12/dist/vue.min.js"></script> <script src="https://unpkg.com/bootstrap-vue@2.21.2/dist/bootstrap-vue.js"></script> <script src="https://unpkg.com/faker@5.5.3/dist/faker.min.js"></script>
<div id="app" class="p-3"> <b-pagination v-model="current_page" :per-page="per_page" :total-rows="total_rows"> </b-pagination>
<h4>Table is refresh with a new item every 5 seconds.</h4> <h6>Click on a row to expand the row</h6> <b-table :items="computed_users" :fields="fields" bordered hover striped :current-page="current_page" :per-page="per_page" @row-clicked="onRowClicked"> <template #cell(avatar)="{ value }"> <b-avatar :src="value"></b-avatar> </template> <template #cell(name)="{ item: { personal_info: { first_name, last_name } }}"> {{ first_name }} {{ last_name }} </template> <template #row-details="{ item }"> <pre>{{ item }}</pre> </template> </b-table> </div>
<!-- end snippet -->

If you're using version 2.0.0 or newer of `bootstrap-vue` you need to change the slot names as they've changed, and the old vue slot has also been deprecated in favor for `v-slot`.
I changed the accepted answers fiddle to work with the new naming and v-slot

<!-- begin snippet: js hide: false console: false babel: false -->
<!-- language: lang-js -->
new Vue({ el: "#app", data: { fields: [{ key: "id", label: "Id", colType: "span" }, { key: "name", label: "Name", colType: "button" }, { key: "uhh", label: "uhh..", colType: "idk" }], items: [{ id: 0, name: "Test 0" }, { id: 1, name: "Test 1" }, { id: 2, name: "Test 2" }] } });
<!-- language: lang-html -->
<link href="https://unpkg.com/bootstrap@4.3.1/dist/css/bootstrap.min.css" rel="stylesheet" /> <link href="https://unpkg.com/bootstrap-vue@2.0.0/dist/bootstrap-vue.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script> <script src="https://unpkg.com/bootstrap-vue@2.0.0/dist/bootstrap-vue.js"></script>

<div id="app"> <b-table :items="items" :fields="fields"> <template v-for="(field, index) in fields" v-slot:[`cell(${field.key})`]="data"> <div v-if="field.colType === 'button'"> <h5>{{data.item.name}}</h5> <b-button>Am Button</b-button> </div> <div v-else-if="field.colType === 'span'"> <h5>{{data.item.name}}</h5> <span>Am Span</span> </div> <div v-else> <h5>{{data.item.name}}</h5> Am Confused </div> </template> </b-table> </div>
<!-- end snippet -->


        
Present in both answers; Present only in the new answer; Present only in the old answer;