1

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:

Relational tables

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:

Table display

As you can see, the FK values are displayed but not the names.

The lookup tables and data to be displayed:

Lookup table data

Data object in chrome:

enter image description here

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>
  1. How do I display the Name field of the referenced table instead of the Foreign Key.

  2. Is there a "better" way to accomplish the task with a "web type" database design?

7
  • Do you have the data from AssetMake/AssetModel in your json object? It looks like you dont have that, according to your screenshot Commented Oct 17, 2019 at 10:25
  • You need to refactor your sql query to include both the column values as assetMake & assetModel Commented Oct 17, 2019 at 11:16
  • @isebarn I do not select the data of AssetMake/AssetModel in the query. If I do include the data, how would I setup the relationship in the code? Commented Oct 17, 2019 at 16:51
  • @chans I can do that to display the text, but when it gets to editing or adding, how would I give the user the options (lookups)? Commented Oct 17, 2019 at 16:53
  • @LouwrensPotgieter check the answer below, I've listed down the changes needs to be done in html and css. Lets me know if this resolves your issue Commented Oct 17, 2019 at 17:00

2 Answers 2

1

Make sure that you api response object should have AssetMake and AssetModel properties, Then make the below changes to html and css. Then it will work as expected

    <v-col cols="12" sm="6" md="4">
                        <v-text-field v-model="editedItem.AssetMake" label="Make"></v-text-field>
                      </v-col>
                      <v-col cols="12" sm="6" md="4">
                        <v-text-field v-model="editedItem.AssetModel" label="Model"></v-text-field>
                      </v-col>
                      <v-col cols="12" sm="6" md="4">      


{ text: 'Name', value: 'Name'},
      { text: 'Make', value: 'AssetMake'},
      { text: 'Model', value: 'AssetModel'},
      { 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: '',
      AssetMake: '',
      AssetModel: '',
      Registration: null,
      Year: null,
      Capacity: null,
      Description: '',
      IsVessel: null
    },
    defaultItem: {
      Name: '',
      AssetMake: '',
      AssetModel: '',
      Registration: null,
      Year: null,
      Capacity: null,
      Description: '',
      IsVessel: null
    }
Sign up to request clarification or add additional context in comments.

Comments

1

@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.

Comments

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.