Home > Net >  Use two fields combined value as the primary key of a b-table in Vue.js
Use two fields combined value as the primary key of a b-table in Vue.js

Time:08-11

I want to construct a b-table containing GitHub Repo information. I used to use the repo id as the primary key, but since I have many repos to manage, an error happened when two repos from different orgs have the same repo id. So I wonder if I could combine the org id and the repo id and use the combined value as the primary key? There doesn't seem to be much discussion about this. Below is how the table currently defined:

      <b-table
        sticky-header="640px"
        striped
        hover
        no-border-collapse
        primary-key="repoid"
        :items="items"
        :filter="filter"
        :fields="fields"
        sort-by="updatedAt"
        :sort-desc="true"
      >

I tried to change the primary key to primary-key="orgid" "-" "repoid" but there seems to be an error. Any suggestions? Thanks in advance!

CodePudding user response:

Rule number one: Do not rely on external values as the primary key, including email addresses, ID card numbers, etc. Make one for yourself.

As a response, your trick doesn't work because the table asks you for the name of a field that contains the primary key. It's crystal clear to me that none of the items contains a field named orgid-repoid

As a solution, build your primary key on demand.

// where you fetch items, make it
items = items.map((x) => ({
  ...x,
  myOwnedPrimaryKey: `${x.orgid}-${x.repoid}`,
}));

Now, feel free to use your owned primary key.

primary-key="myOwnedPrimaryKey"

CodePudding user response:

You can just augment the b-table items with a computed primary key. In the snippet here, the table items come from a computed property called keyedItems which adds a prop called thePrimaryKey. For illustration, it combines data from the item (first_name) and the index.

To see it working, run the snippet, then inspect one of the table rows with browser dev tools. The b-table combines that with the table's id, to produce rows with ids (in this example) like these:

myTable__row_Dickerson_-_0
myTable__row_Larsen_-_1
...

Vue.config.productionTip = false;
Vue.config.devtools = false;

var app = new Vue({
  el: '#app',
  computed: {
    keyedItems() {
      return this.items.map((item, index) => {
        return { ...item, thePrimaryKey: `${item.first_name} - ${index}` };
      })
    }
  },
  data() {
    return {
      // Note `isActive` is left out and will not appear in the rendered table
      fields: ['first_name', 'last_name', 'age'],
      items: [{
          isActive: true,
          age: 40,
          first_name: 'Dickerson',
          last_name: 'Macdonald'
        },
        {
          isActive: false,
          age: 21,
          first_name: 'Larsen',
          last_name: 'Shaw'
        },
        {
          isActive: false,
          age: 89,
          first_name: 'Geneva',
          last_name: 'Wilson'
        },
        {
          isActive: true,
          age: 38,
          first_name: 'Jami',
          last_name: 'Carney'
        }
      ]
    }
  }

})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" />
<script src="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue-icons.min.js"></script>

<div id="app">
  <div>
    <b-table 
      id="myTable"
      primary-key="thePrimaryKey"
      striped 
      hover
      :items="keyedItems"
      :fields="fields" 
    >
    </b-table>
  </div>
</div>

  • Related