Kavvson Empcraft
Kavvson Empcraft

Reputation: 443

Undefined variable - While api fetch | Axios | Props

My main component - Home

A really simple component, I pass the fetch variable to another component.

<template>
      <Page actionBarHidden="true">
        <ComponentA :api="api.somevariable"></ComponentA>
      </Page>
    </template>

    <script>
    import axios from "axios";
    import ComponentA from "./ComponentA.vue";
    export default {
      data() {
        return {
          isLoading: false,
          result: []
        };
      },
       components: {
        ComponentA,
      },
       created() {
        this.loadData();
      },
       methods: {
           async loadData() {
              let self = this;

              console.log("fetch");

              self.isLoading = true;
              const { data } = await Endpoints.get();
              self.isLoading = false;
              self.api = data;
              console.log(data); // returns the data as intended
            }
       }
    </script>

The componentA is also simple

<template>
  <Label :text="somevariable"></Label>
</template>
<script>
export default {
  data() {
    return {
      somevariable: 0
    };
  },
  props: {
    api: {
      type: Number,
      required: true
    }
  },
  mounted() {
     this.somevariable = this.api;
  }
};
</script>

The error I am getting is [Vue warn]: Invalid prop: type check failed for prop "api". Expected Number with value NaN, got Undefined in the componentA, after some quoting and requoting of console.logs it actually picks up the value. I am not sure why is that, is my approach wrong? This frustrates me, can't figure it out for some hours already.

Upvotes: 0

Views: 678

Answers (1)

skirtle
skirtle

Reputation: 29112

api isn't defined in the data for the first component, so it won't be reactive. That should be giving you a warning message in the console.

data () {
  return {
    api: null,
    isLoading: false,
    result: []
  };
}

The second problem is that when the component first renders it won't yet have loaded api from the server. Using await won't help with this, rendering the template will happen before the asynchronous request has completed.

Given the way componentA is currently written it won't be able to cope with api being missing when it is first created. So you'll need to use a v-if to defer creation until that data is available:

<ComponentA v-if="api" :api="api.somevariable"></ComponentA>

Without the v-if check it'll just be passing the initial value of api, which in your original code is undefined. That is what caused the warning mentioned in the question.

When you talk about 'quoting and requoting of console.logs', I would assume that those changes are just triggering hot reloading, which could easily cause components to re-render with the new data. That wouldn't happen otherwise because of the lack of reactivity caused by api not being included in the original data.

Upvotes: 1

Related Questions