Search code examples
vue.jsvuejs2airtable

Airtable data into Vue.js


I am new to vue js and have been trying for hours to get airtable data into my application. I am hoping someone could help me as I feel I am almost there! I am using the Airtable NPM package to retrieve the data - https://www.npmjs.com/package/airtable

    <template>
  <section id="cards-section" class="cards-section">
    <div class="centered-container w-container">
      <h1>{{ msg }}</h1>
      <div class="cards-grid-container">
        <Card />
        <ul id="example-1">
          <li v-for="item in recordsList" v-bind:key="item">
            data here {{ item }}
          </li>
        </ul>
      </div>
    </div>
  </section>
</template>

<script>
import Card from "../components/Card.vue";
import Airtable from "airtable";

export default {
  name: "Main",
  components: {
    Card,
  },
  props: {
    msg: String,
  },
  data() {
    return {
      recordsList: [],
    };
  },
  mounted() {
    const base = new Airtable({ apiKey: "******" }).base(
      "******"
    );

    base("Table 1")
      .select({
        view: "Grid view",
      })
      .firstPage(function (err, records) {
        if (err) {
          console.error(err);
          return;
        }
        records.forEach( (record) => {
          console.log(record.get("Name"));
          return record.get("Name")
        });
      });
  },
};
</script>

<style scoped>
</style>

Solution

  • Looking at your code you are probably at the stage that you have succesfully retrieved the data from airtable and seeing some records in your console.log.

    Now how to get them from inside that function to your Vue instance:

    I will show you two ways to go about this and explain them later:

    Method 1: Using a reference to self.

    <script>
    import Card from "../components/Card.vue";
    import Airtable from "airtable";
    
    export default {
      name: "Main",
      components: {
        Card,
      },
      props: {
        msg: String,
      },
      data() {
        return {
          recordsList: [],
        };
      },
      mounted() {
        // create a reference to this vue instance here.
        var self = this;
    
        const base = new Airtable({ apiKey: "******" }).base(
          "******"
        );
    
        base("Table 1")
          .select({
            view: "Grid view",
          })
          .firstPage(function (err, records) {
            if (err) {
              console.error(err);
              return;
            }
    
            // now we can set the recordList of our
            // vue instance: 
            self.recordsList = records;
          });
      },
    };
    </script>
    

    Method 2: Using javascript arrow function:

    <script>
    import Card from "../components/Card.vue";
    import Airtable from "airtable";
    
    export default {
      name: "Main",
      components: {
        Card,
      },
      props: {
        msg: String,
      },
      data() {
        return {
          recordsList: [],
        };
      },
      mounted() {
        // no need to create a reference this time.
    
        const base = new Airtable({ apiKey: "******" }).base(
          "******"
        );
    
        base("Table 1")
          .select({
            view: "Grid view",
          })
          .firstPage( (err, records) => {
            if (err) {
              console.error(err);
              return;
            }
    
            this.recordsList = records;
    
          });
      },
    };
    </script>
    

    Now what was the problem? In the first example we use a normal javascript anonymous function. this inside a normal javascript anonymous function is not what you expect it to be. We solve this by defining a reference to this (var self = this) somewhere and instead of trying this.recordsList we do self.recordsList inside our anynomous function.

    Nem improvements to the javascript language introduced another type of function, the arrow function. One benefit of this function is that this inside this function is the object that you've defined it in. So, this is our vue instance. Now we don't have a problem and can just set this.recordsList.

    Other solutions i've ommitted are:

    • Using Function.bind
    • async/await