I created a Node App with Vue.js, Vuetify (Client side of app) and Express (Server side of App) and the data is stored in a SQL Server database (relational database).
Everything is up and running on my development machine and connection between client, server and database is working.
I just don’t know how to display “Lookup Data/relational data” in the tables that I am using.
3 tables of my database:
So I would like to display the Name fields of AssetMake and AssetModel INSTEAD of the FKAssetMake and FKAssetModel.
This is a screenshot of my table in the browser:
As you can see, the FK values are displayed but not the names.
The lookup tables and data to be displayed:
Data object in chrome:
My Vue template:
<template> <div id="app"> <v-app id="inspire"> <v-card> <v-card-title> Asset (Vehicle/Vessel) <v-spacer></v-spacer> <v-text-field v-model="search" label="Search" append-icon="mdi-card-search-outline" single-line hide-details ></v-text-field> </v-card-title> <v-data-table dense :headers="headers" :items="assets" :search="search" sort-by="Name" class="elevation-1" > <template v-slot:top> <v-toolbar flat color="white"> <v-toolbar-title>{{ tabelHeader }}</v-toolbar-title> <v-spacer></v-spacer> <v-dialog v-model="dialog" max-width="500px"> <template v-slot:activator="{ on }"> <v-btn color="primary" dark class="mb-2" v-on="on">New Item</v-btn> </template> <v-card> <v-card-title> <span class="headline">{{ formTitle }}</span> </v-card-title> <v-card-text> <v-container> <v-row> <v-col cols="12" sm="6" md="4"> <v-text-field v-model="editedItem.Name" label="Name"></v-text-field> </v-col> <v-col cols="12" sm="6" md="4"> <v-text-field v-model="editedItem.FKMake" label="Make"></v-text-field> </v-col> <v-col cols="12" sm="6" md="4"> <v-text-field v-model="editedItem.FKModel" label="Model"></v-text-field> </v-col> <v-col cols="12" sm="6" md="4"> <v-text-field v-model="editedItem.Registration" label="Registration"></v-text-field> </v-col> <v-col cols="12" sm="6" md="4"> <v-text-field v-model="editedItem.Description" label="Description"></v-text-field> </v-col> <v-col cols="12" sm="6" md="4"> <v-text-field v-model="editedItem.Year" label="Year"></v-text-field> </v-col> <v-col cols="12" sm="6" md="4"> <v-text-field v-model="editedItem.Capacity" label="Capacity"></v-text-field> </v-col> <v-col cols="12" sm="6" md="4"> <v-text-field v-model="editedItem.isVessel" label="Is Vessel"></v-text-field> </v-col> </v-row> </v-container> </v-card-text> <v-card-actions> <v-spacer></v-spacer> <v-btn color="blue darken-1" text @click="close">Cancel</v-btn> <v-btn color="blue darken-1" text @click="save">Save</v-btn> </v-card-actions> </v-card> </v-dialog> </v-toolbar> </template> <template v-slot:item.Action="{ item }"> <v-icon small class="mr-2" @click="editItem(item)" > edit </v-icon> <v-icon small @click="deleteItem(item)" > delete </v-icon> </template> </v-data-table> </v-card> </v-app> </div> </template>
Script part:
<script> import appConfig from '../config/appConfig.js' const baseURL = "http://" + appConfig.server.ip + ":" + appConfig.server.port export default { data: () => ({ search: '', dialog: false, tabelHeader: '', assets: [], headers: [ { text: 'Name', value: 'Name'}, { text: 'Make', value: 'FKMake'}, { text: 'Model', value: 'FKModel'}, { text: 'Registration', value: 'Registration'}, { text: 'Description', value: 'Description' }, { text: 'Year', value: 'Year' }, { text: 'Capacity', value: 'Capacity' }, { text: 'Vessel', value: 'IsVessel' }, { text: 'Actions', value: 'Action', sortable: false } ], editedIndex: -1, editedItem: { Name: '', FKMake: -1, FKModel: -1, Registration: null, Year: null, Capacity: null, Description: '', IsVessel: null }, defaultItem: { Name: '', FKMake: -1, FKModel: -1, Registration: null, Year: null, Capacity: null, Description: '', IsVessel: null } }), watch: { dialog (val) { val || this.close() }, }, methods:{ editItem (item) { this.editedIndex = this.assets.indexOf(item) this.editedItem = Object.assign({}, item) this.dialog = true }, deleteItem (item) { const index = this.assets.indexOf(item) var isDelete = confirm('Are you sure you want to delete this item?') if (isDelete) { this.deleteAssetMake(item, index) } }, close () { this.dialog = false setTimeout(() => { this.editedItem = Object.assign({}, this.defaultItem) this.editedIndex = -1 }, 300) }, save () { if (this.editedIndex > -1) { Object.assign(this.assets[this.editedIndex], this.editedItem) this.updateAssetMake(this.editedItem) } else { this.assets.push(this.editedItem) this.addAssetMake(this.editedItem) } this.close() }, deleteAssetMake (asset, index) { fetch(baseURL + '/api/asset/' + asset.ID, { method: 'DELETE' }) .then(() => { this.assets.splice(index, 1) }) }, updateAssetMake (asset) { fetch(baseURL + '/api/asset/' + asset.ID, { body: JSON.stringify(asset), method: 'PUT', headers: { 'Content-Type': 'application/json' } }) .then(() => { }) }, addAssetMake (asset) { fetch(baseURL + '/api/asset/', { body: JSON.stringify(asset), method: 'POST', headers: { 'Content-Type': 'application/json' } }) } }, mounted () { fetch(baseURL + '/api/asset') .then(response => response.json()) .then((data) => { this.assets = data.resultMessage console.log(data.resultMessage) }) //.catch(() => console.log('Can’t access response. Blocked by browser?')) }, computed: { formTitle () { return this.editedIndex === -1 ? 'New Item' : 'Edit Item' }, } } </script>
How do I display the Name field of the referenced table instead of the Foreign Key.
Is there a “better” way to accomplish the task with a “web type” database design?
Advertisement
Answer
@chans’s answer got me on the right track.
As the users will not be editing the data in the table ‘in-line”, one can change the query to show the data needed (AssetMake.Name and AsseteModel.Name).
I am using a dialog with a form to do the editing and adding of Assets. I then use a v-select to display the lookup data like this:
<v-col cols="12" sm="6" md="4"> <v-select v-model="editedItem.FKModel" :items="assetModels" item-text="Name" item-value="ID" label="Model" autocomplete></v-select> </v-col>
assetModels contains all asset models and was fetched from the database on mounted event.
Thanks to all who participated.