No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    Using REST API with VueJS

    Help
    3
    11
    5859
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • J
      jreqthek9 last edited by

      I have an employees.json file stored in the “statics” folder of my local VueJS project. The Index.vue file is displaying data from that local employees.json file. However, the json file was downloaded from the website http://dummy.restapiexample.com/ which contains fake online REST APIs for testing and prototyping of sample applications which are using rest call to display listing and crud features.

      What I would like to do is use the REST library for Vue.js to load the /employee data found on http://dummy.restapiexample.com/ in real time, making update calls each time, instead of simply changing the json object stored in the employees.json file. In other words, instead of relying on the local json file for displaying the data, I would like to use the /employee data in the REST API instead. How is this done? Apparently I need Axios in order to make this possible. Do I need Vuex to complete this?

      <template>
        <div class="q-pa-md">
          <q-markup-table>
            <thead>
              <tr>
                <th class="text-left">Id</th>
                <th class="text-left">Employee Name</th>
                <th class="text-right">Employee Salary</th>
                <th class="text-right">Employee Age</th>
                <th class="text-right">Profile Image</th>
                <th class="text-right">Delete</th>
              </tr>
            </thead>
            <tbody>
              <tr
                v-for="(data, index) in myJson"
                :key="index"
              >
                <td class="text-left">{{data.id}}</td>
                <td class="text-right"><a
                    href="javascript:void(0)"
                    @click="editEmployee(data.id)"
                  >{{data.employee_name}}</a></td>
                <td class="text-right">{{data.employee_salary}}</td>
                <td class="text-right">{{data.employee_age}}</td>
                <td class="text-right">{{data.profile_image}}</td>
                <td class="text-right">
                  <q-btn
                    flat
                    icon="delete"
                    color="negative"
                    @click="deleteEmployee(data.id)"
                  />
                </td>
              </tr>
            </tbody>
          </q-markup-table>
          <q-dialog
            v-model="editModal"
            @hide="cancelEditEmployee"
          >
            <q-card
              style="width: 700px; max-width: 80vw;"
              v-if="employee !== null"
            >
              <q-card-section>
                <div class="text-h6">Employee: {{employee.employee_name}}</div>
              </q-card-section>
      
              <q-card-section class="q-pt-none">
                <q-input
                  outlined
                  v-model="employee.employee_name"
                  label="Employee Name"
                  class="q-mb-md"
                />
      
                <q-input
                  outlined
                  v-model="employee.employee_salary"
                  label="Salary"
                  class="q-mb-md"
                  type="number"
                />
      
                <q-input
                  outlined
                  v-model="employee.employee_age"
                  label="Age"
                  class="q-mb-md"
                  type="number"
                />
              </q-card-section>
      
              <q-card-actions
                align="center"
                class="bg-white text-teal"
              >
                <q-btn
                  label="Save"
                  color="positive"
                  @click="saveEmployee"
                  v-close-popup
                />
                <q-btn
                  color="negative"
                  label="Cancel"
                  v-close-popup
                />
              </q-card-actions>
            </q-card>
          </q-dialog>
        </div>
      </template>
      
      <script>
      import json from '../statics/employees.json'
      export default {
        data () {
          return {
            myJson: [],
            editModal: false,
            employee: null,
            editingIndex: null
          }
        },
        methods: {
          deleteEmployee (id) {
            this.$q.dialog({
              title: 'Confirm',
              message: 'Would you really like to delete?',
              cancel: true,
              persistent: true
            }).onOk(() => {
              var index = this.myJson.findIndex(e => e.id === id)
              if (index > -1) {
                this.myJson.splice(index, 1)
              }
            })
          },
          editEmployee (id) {
            var index = this.myJson.findIndex(e => e.id === id)
            if (index > -1) {
              this.editingIndex = index
              this.employee = JSON.parse(JSON.stringify(this.myJson[index]))
              this.editModal = true
            } else {
              console.log('something went wrong')
            }
          },
          cancelEditEmployee () {
            this.employee = null
            this.editingIndex = null
          },
          saveEmployee () {
            this.myJson[this.editingIndex] = JSON.parse(JSON.stringify(this.employee))
            this.editModal = false
          }
        },
        mounted () {
          this.myJson = JSON.parse(JSON.stringify(json)).data
        }
      }
      </script>
      
      1 Reply Last reply Reply Quote 0
      • s.molinari
        s.molinari last edited by

        Yes. You need Axios to consume a web api. Whether or not state needs to be updated across your components determines your need for Vuex or not.

        Scott

        1 Reply Last reply Reply Quote 0
        • M
          mdcode224 last edited by

          update your mounted method to:

          mounted () {
              axios('http://dummy.restapiexample.com/data-path')
                  .then(response => {
                      this.myJson = JSON.parse(response.data)
                  })
                  .catch(error => console.log('Error',  error.message))
            }
          
          1 Reply Last reply Reply Quote 0
          • J
            jreqthek9 last edited by

            I replaced the mounted () method at the bottom of my Javascript code with the example above, which now looks like this:

            <script>
            const axios = require('axios')
            import json from '../statics/employees.json'
            export default {
              data () {
                return {
                  myJson: [],
                  editModal: false,
                  employee: null,
                  editingIndex: null
                }
              },
              methods: {
                deleteEmployee (id) {
                  this.$q.dialog({
                    title: 'Confirm',
                    message: 'Would you really like to delete?',
                    cancel: true,
                    persistent: true
                  }).onOk(() => {
                    var index = this.myJson.findIndex(e => e.id === id)
                    if (index > -1) {
                      this.myJson.splice(index, 1)
                    }
                  })
                },
                editEmployee (id) {
                  var index = this.myJson.findIndex(e => e.id === id)
                  if (index > -1) {
                    this.editingIndex = index
                    this.employee = JSON.parse(JSON.stringify(this.myJson[index]))
                    this.editModal = true
                  } else {
                    console.log('something went wrong')
                  }
                },
                cancelEditEmployee () {
                  this.employee = null
                  this.editingIndex = null
                },
                saveEmployee () {
                  this.myJson[this.editingIndex] = JSON.parse(JSON.stringify(this.employee))
                  this.editModal = false
                }
              },
              mounted () {
                axios('http://dummy.restapiexample.com/data-path')
                  .then(response => {
                    this.myJson = JSON.parse(response.data)
                  })
                  .catch(error => console.log('Error', error.message))
              }
            }
            </script>
            

            However, ESLint is reporting an error:

            In the import line at the top of the code, ESLint is saying “‘json’ is defined but never used”. I assume this is because I am importing the data from the REST API location and not from the local employees.json file anymore. Do I replace import/export with a different command?

            1 Reply Last reply Reply Quote 0
            • s.molinari
              s.molinari last edited by

              Remove your import of json.

              Also, import axios. And, if you’re going to use it more often, you’ll probably want to “add” it.

              https://medium.com/quasar-framework/adding-axios-to-quasar-dbe094863728

              Scott

              1 Reply Last reply Reply Quote 0
              • J
                jreqthek9 last edited by

                Okay, so very close to success. Following s.molinari’s advice, I created a new Quasar project, adding both ESLint and Axios during the installation, and copy/pasted the Index.vue code to the new project. I also edited the axios.js file as described in the link s.molinari sent. However, after doing all that, the dev screen just shows the top table header and not the table content in the REST API link.

                dev screen

                <template>
                  <div class="q-pa-md">
                    <q-markup-table>
                      <thead>
                        <tr>
                          <th class="text-left">Id</th>
                          <th class="text-left">Employee Name</th>
                          <th class="text-right">Employee Salary</th>
                          <th class="text-right">Employee Age</th>
                          <th class="text-right">Profile Image</th>
                          <th class="text-right">Delete</th>
                        </tr>
                      </thead>
                      <tbody>
                        <tr
                          v-for="(data, index) in myJson"
                          :key="index"
                        >
                          <td class="text-left">{{data.id}}</td>
                          <td class="text-right"><a
                              href="javascript:void(0)"
                              @click="editEmployee(data.id)"
                            >{{data.employee_name}}</a></td>
                          <td class="text-right">{{data.employee_salary}}</td>
                          <td class="text-right">{{data.employee_age}}</td>
                          <td class="text-right">{{data.profile_image}}</td>
                          <td class="text-right">
                            <q-btn
                              flat
                              icon="delete"
                              color="negative"
                              @click="deleteEmployee(data.id)"
                            />
                          </td>
                        </tr>
                      </tbody>
                    </q-markup-table>
                    <q-dialog
                      v-model="editModal"
                      @hide="cancelEditEmployee"
                    >
                      <q-card
                        style="width: 700px; max-width: 80vw;"
                        v-if="employee !== null"
                      >
                        <q-card-section>
                          <div class="text-h6">Employee: {{employee.employee_name}}</div>
                        </q-card-section>
                
                        <q-card-section class="q-pt-none">
                          <q-input
                            outlined
                            v-model="employee.employee_name"
                            label="Employee Name"
                            class="q-mb-md"
                          />
                
                          <q-input
                            outlined
                            v-model="employee.employee_salary"
                            label="Salary"
                            class="q-mb-md"
                            type="number"
                          />
                
                          <q-input
                            outlined
                            v-model="employee.employee_age"
                            label="Age"
                            class="q-mb-md"
                            type="number"
                          />
                        </q-card-section>
                
                        <q-card-actions
                          align="center"
                          class="bg-white text-teal"
                        >
                          <q-btn
                            label="Save"
                            color="positive"
                            @click="saveEmployee"
                            v-close-popup
                          />
                          <q-btn
                            color="negative"
                            label="Cancel"
                            v-close-popup
                          />
                        </q-card-actions>
                      </q-card>
                    </q-dialog>
                  </div>
                </template>
                
                <script>
                import axios from 'axios' // NOT const axios = require('axios')
                
                export default {
                  data () {
                    return {
                      myJson: [],
                      editModal: false,
                      employee: null,
                      editingIndex: null
                    }
                  },
                  methods: {
                    deleteEmployee (id) {
                      this.$q.dialog({
                        title: 'Confirm',
                        message: 'Would you really like to delete?',
                        cancel: true,
                        persistent: true
                      }).onOk(() => {
                        var index = this.myJson.findIndex(e => e.id === id)
                        if (index > -1) {
                          this.myJson.splice(index, 1)
                        }
                      })
                    },
                    editEmployee (id) {
                      var index = this.myJson.findIndex(e => e.id === id)
                      if (index > -1) {
                        this.editingIndex = index
                        this.employee = JSON.parse(JSON.stringify(this.myJson[index]))
                        this.editModal = true
                      } else {
                        console.log('something went wrong')
                      }
                    },
                    cancelEditEmployee () {
                      this.employee = null
                      this.editingIndex = null
                    },
                    saveEmployee () {
                      this.myJson[this.editingIndex] = JSON.parse(JSON.stringify(this.employee))
                      this.editModal = false
                    }
                  },
                  mounted () {
                    axios
                      .get('http://dummy.restapiexample.com/api/v1/employees')
                      .then(response => {
                        this.myJson = JSON.parse(response.data)
                      })
                      .catch(error => console.log('Error', error.message))
                  }
                }
                </script>
                

                Axios.js is below:

                import axios from 'axios'
                const axiosInstance = axios.create({
                  baseURL: 'https://api.example.com'
                })
                export default ({ Vue }) => {
                  Vue.prototype.$axios = axios
                }
                export { axiosInstance }
                

                The same result occurs whether I have “import axios from ‘axios’” or “const axios = require(‘axios’)” in the first Javascript line. The table does not fill up with the API’s information.

                1 Reply Last reply Reply Quote 0
                • s.molinari
                  s.molinari last edited by

                  https://codesandbox.io/s/pensive-hawking-50o5j

                  Scott

                  1 Reply Last reply Reply Quote 0
                  • J
                    jreqthek9 last edited by

                    Yes! That works. I had a slight feeling that JSON.parse command in the mounted () section didn’t look right but wasn’t sure how to replace it. Thanks a ton!

                    1 Reply Last reply Reply Quote 0
                    • J
                      jreqthek9 last edited by

                      A follow-up:

                      So using Axios, it’s possible to implement CRUD (Create, Read, Update and Delete) functionality in the database. In the previous example, the GET request was added at the end of the Javascript to get the list of employee information. Now if I wanted to add additional CRUD commands - like the DELETE request for a user to click the Delete button in any row and send a response back to the API saying to actually delete the row information, and refresh the grid - would I add them in the mounted () section of Javascript? The example below does not work:

                       mounted () {
                          this.$axios
                            .get('https://dummy.restapiexample.com/api/v1/employees')
                            .then(response => {
                              this.myJson = response.data.data
                            })
                            .catch(error => console.log('Error', error.message))
                        },
                          this.$axios
                            .delete('https://dummy.restapiexample.com/api/v1/employees')
                            .then(response => {
                              this.myJson = response.data.data
                            })
                            .catch(error => console.log('Error', error.message))
                        }
                      }
                      
                      1 Reply Last reply Reply Quote 0
                      • s.molinari
                        s.molinari last edited by

                        mounted is a Vue lifecycle hook. It only fires once, when the component is “mounted”.

                        For the delete, you need a method that fires on the @click event of a button (or a confirmation dialog).

                        This is very basic Vue/ JavaScript stuff. Don’t mean to be condescending, but you really should take to the books. We aren’t here to teach you Vue or JavaScript. Ok?

                        For a good Vue course, I’d suggest taking this: https://www.udemy.com/course/vuejs-2-the-complete-guide

                        Scott

                        1 Reply Last reply Reply Quote 0
                        • J
                          jreqthek9 last edited by

                          Okay, I’ll do that. Thanks.

                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post