0
votes

I'm experimenting with the Composition API with Vue3. But there were some points I couldn't find. The same code did not work in two different projects.

What I want to do in my own project is to take the data through the API and use it according to what is required. In short, do the necessary get/post operations. I got this API from Vue's own example.

This is the first project code, package.json and error message

<template>
  <div class="home">
    <div v-for="datas in data" :key="datas.description">
      {{ datas.description }}
    </div>
  </div>
</template>

<script lang="ts">
import { Options, Vue } from "vue-class-component";
import axios from "axios";
import { ref } from "vue";

@Options({
  props: {
    msg: String,
  },
})
export default class HelloWorld extends Vue {
  setup() {
    let data = ref([]);
    axios
      .get("https://api.coindesk.com/v1/bpi/currentprice.json")
      .then((res) => {
        data.value = res.data.bpi;
      });
  }
}
</script>

{
  "name": "api-project",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "axios": "^0.21.1",
    "core-js": "^3.6.5",
    "vue": "^3.0.0",
    "vue-class-component": "^8.0.0-0",
    "vue-router": "^4.0.0-0"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-router": "~4.5.0",
    "@vue/cli-plugin-typescript": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/compiler-sfc": "^3.0.0",
    "node-sass": "^4.12.0",
    "sass-loader": "^8.0.2",
    "typescript": "~4.1.5"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

Vue warn

This is the second project code, package.json, and data

<template>
  <div v-for="datas in data" :key="datas.description">
    {{ datas.description }}
  </div>
</template>

<script lang="ts">
import axios from "axios";
import { ref } from "vue";

export default {
  name: "HelloWorld",
  setup() {
    let data = ref([]);
    axios.get("https://api.coindesk.com/v1/bpi/currentprice.json").then((res) => {
      data.value = res.data.bpi;
    });

    return {
      data,
    };
  },
}
</script>

{
  "name": "test-api",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "axios": "^0.21.1",
    "core-js": "^3.6.5",
    "vue": "^3.0.0"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/compiler-sfc": "^3.0.0",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^7.0.0",
    "node-sass": "^4.12.0",
    "sass-loader": "^8.0.2",
    "typescript": "~4.1.5"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/vue3-essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "babel-eslint"
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

my data

Could there be an error in my Composition API usage? I've heard that in some videos, "then" is not used for the Composition API. But that's the only way I was able to pull the data from the API.

If my solution is wrong, what method should it be, I'm new at Vuejs can you help?

2
You need to return the variables from the setup function so that they could be used during rendering. - Chin. Udara

2 Answers

0
votes

You need to return the variables from the setup function so that they can be accessed from within the template.

If setup returns an object, the properties on the object can be accessed in the component's template, as well as the properties of the props passed into setup:

setup() {
    let data = ref([]);
    axios
      .get("https://api.coindesk.com/v1/bpi/currentprice.json")
      .then((res) => {
        data.value = res.data.bpi;
      });
      // return the data as an object
      return {
          data
      }
  }

Read more about this in the official vue doc

0
votes

You can create api dir inside src folder and then inside api dir create a file api.ts and put this code

export async function callApi(endpoint :string, method :string){
    return await fetch(endpoint,{
        method:method,
        headers: {
                'Content-type': 'application/json; charset=UTF-8',
        },
    }).then(async response => {
        const resData = await response.json()
        if (!response.ok) {
            // do something to determine request is not okay
             resData.isSuccess = false
        }
        return resData
    }).catch(error => {
        console.log("callApi in api.ts  err")
        console.log(error)
        throw error
    })
}

Go to you component and use this code

<template>
    <div  v-for="(item,i) in data.records" v-bind:key="i">
      {{ item.chartName}}
    </div>
</template>

<script>
import {onMounted,reactive} from "vue"
import {callApi} from "@/api/api"

export default{
    name:'MyComponent',
    setup() {

        const data = reactive({
            records: [],
        })

        onMounted( async() =>{
            getRecords()
        })

         const getRecords = async() => {
            let resData = await callApi('https://api.coindesk.com/v1/bpi/currentprice.json', 'GET')
            data.records = resData
        }

        return {
          data,
        }
    }
   }
</script>
enter code here