amaturePy
amaturePy

Reputation: 67

How to make a dynamic dropdown with Ajax in Vue.js

I'm newbie to Vue.js. I've been stock in making a dynamic dropdown with Ajax in Vue.js. I have no idea how to populate the select tag with data from the API that is hosted in Google App Engine (GAE) and made in Flask.

File index.html

<div id="app2">
    <select v-model="table_list">
        <option v-for="item in table_list" :value="item">{{ item }}</option>
    </select>
</div>
new Vue({
  el: '#app2',
  data: {
    table_list: []
  },
  created: function () {
    var tableList = this.tableList
    axios.get('API_URL').then(function (response) {
      for (var i = 0; i < response.data.length; i++) {
        tableList.push(response.data[i])
      }
    }).catch(function (error) {
      console.log('failure')
    })
  }

The data of the API:

["test","test1","test2","test3"]

File flask.py

from flask import Flask, request
from google.cloud import bigquery
from flask import jsonify

app = Flask(__name__)

@app.route('/')
def tables_list():
    client = bigquery.Client()
    dataset_id = 'test_table'
    tables = client.list_tables(dataset_id)  # Make an API request.
    tables_list = [];

    for table in tables:
        tables_list.append(table.table_id)
    return jsonify(tables_list)

if __name__ == "__main__":
    app.run()

Upvotes: 0

Views: 2174

Answers (2)

Ruslan Isay
Ruslan Isay

Reputation: 1011

You can consider using an existing flexible solution for selects/dropdowns with built-in support of dynamic contents.

E.g. Vue-Multiselect.

Upvotes: 1

Lawrence Cherone
Lawrence Cherone

Reputation: 46602

v-model="table_list" should be a selected model, not the list itself.

<select v-model="table_list_selected">
   <option v-for="item in table_list">{{ item }}</option>
</select>

And data: should return a function, plus the model name is table_list, not tableList

new Vue({
  el: '#app2',
  data: () => ({
    table_list: [],
    table_list_selected: ''
  }),

Also, when you want to keep the scope of this when calling a function, either use arrow functions, or bind this to the function or do away with the callback and use async/await.

created: function () {
    axios.get('API_URL').then(response => {
      this.table_list = response.data
    }).catch(function (error) {
      console.log('failure')
    })
}

Or with bind()

created: function () {
    axios.get('API_URL').then(function(response) {
      this.table_list = response.data
    }.bind(this)).catch(function (error) {
      console.log('failure')
    })
}

Or with async/await

created: async function () {
    try {
       this.table_list = await axios.get('API_URL').data
    } catch (e) {
       console.log('failure')
    }
}

Upvotes: 1

Related Questions