2

I'm new to Vue.JS and JavaScript, so I have awful times debugging these applications, specially with promises and asynchronous tools. I'm trying to build my first Vue component that fetches data from somewhere. I'm using the Google Sheets API and returning some cells of a sample sheet. My component looks like this:

<template>
<ul>
  <li v-for="athlete in athletes" :key="athlete">
    {{ athlete }}
  </li>
</ul>
</template>

<script>
import readCopaPinheiros from '@/sheets/fetchData.js';

export default {
  name: 'AthletesTable',
  data () {
    return {
      loading: false,
      athletes: null
    }
  },
  created () {
    this.fetchData()
  },
  methods: {
    fetchData() {
      this.loading = true;
      readCopaPinheiros('inscritos').then(values => {
        this.loading = false;
        console.log(values)
        this.athletes = values
      });
    },
  } 
}
</script>

<style>
</style>

EDIT 1

The fetchData script:

const fs = require('fs');
const { google } = require('googleapis');
const TOKEN_PATH = '';
const CREDENTIALS_PATH = ''

const credentials = JSON.parse(fs.readFileSync(CREDENTIALS_PATH, 'utf-8'));

const {
client_secret: clientSecret,
client_id: clientId,
redirect_uris: redirectUris,
} = credentials.installed;

const oAuth2Client = new google.auth.OAuth2(
  clientId, clientSecret, redirectUris[0],
);

const token = fs.readFileSync(TOKEN_PATH, 'utf-8');
oAuth2Client.setCredentials(JSON.parse(token));

async function readSheet(spreadsheetId, range) {
  const sheets = google.sheets({ version: 'v4', auth: oAuth2Client });

  return sheets.spreadsheets.values.get({
    spreadsheetId,
    range,
  })
  .then(res => res.data.values)
  .catch(err => console.log('Opa! Erro:', err));
}

function readSheetJsnofied(spreadsheetId, range) {
    return readSheet(spreadsheetId, range)
      .then(values => jsonifySheet(values));
}

function jsonifySheet(sheetValues) {
  const header = sheetValues[0];
  const values = sheetValues.slice(1);
  return values.map((row) => {
    const rowObj = ({});
    for (let i=0; i < row.length; i++) rowObj[header[i]] = row[i];
    return rowObj;
  });
}

const readCopaPinheiros = d => readSheetJsnofied('sheetId', d);

export default readCopaPinheiros

For some reason the component doesn't render. I don't know what to do even to debug, all my console log tries never prints something to the console. Could someone help me understand what is going wrong?

EDIT 2

This error just shows up when trying to fetch data: enter image description here When I try to use a placeholder list with fake values directly in the data function it works. I don't believe that is a problem with the rendering itself, but how it interacts with the created and fetchData functions.

7
  • 1
    Can you open the browsers debugging tools (F12), click the "Network" tab, and see if the network request to the Google Sheets API is being executed successfully? Commented Jul 11, 2020 at 1:56
  • There is no explicit call to the Google Sheets API. I'm using their googleapis package. I know that there is a OAuth running underneath, I followed this tutorial: morioh.com/p/1313d7785668. After it worked in the node console I just imported inside the component. What I'm saying is that if open a node shell and require the readCopaPinheiros function it works properly. I don't know exactly if there is some deeper stuff hidden. Commented Jul 11, 2020 at 2:00
  • There are also a bunch of webpack errors that I can't decipher. They don't appear when the created and method fields are removed. This is the main message "Uncaught TypeError: Expected input to be a Function or Object, got undefined" Commented Jul 11, 2020 at 2:14
  • can you show the code of '@/sheets/fetchData.js' or readCopaPinheiros? most probably your promise is not resolving since the console not show anything as you said. Commented Jul 11, 2020 at 3:07
  • I've added the code to the question. Commented Jul 11, 2020 at 12:32

1 Answer 1

1
v-for="athlete in athletes"

This code only works when the athletes is an array. Initially, you set it as null so until the data from api is arrived, it will be null. But the component still tries to render the component with your null athletes and will make the error. You can try with this solution:

data () {
  return {
      loading: false,
      athletes: []
  }
},
Sign up to request clarification or add additional context in comments.

1 Comment

I think that is not the case. I just tested your suggestion but it didn't work. I think that there is some problem with the fetchData script, the fetchCopaPinheiros returns a list and the rendering should work. Actually, with placeholder values it works but when trying to get the data from the googlesheets API it stop working.

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.