blackrox
blackrox

Reputation: 231

Provide/inject axios response

I have one component in which I use axios to get data from API, it works and I can use this data in this component, but when I try to provide this data to another component, I dont get any data there. Here is part of my code:

  data() {
    return {
      theme: [],
    };
  },
  provide() {
   return {
     theme: this.theme
   }
  },
  methods: {
    getTheme() {
      axios
        .get(here is my api url)
        .then((response) => (this.theme = response.data.data));
    },
  },
  mounted() {
    this.getTheme();
  },

and this is the second component:

<template>
  <div class="project-wrapper">
    <project-card
    v-for="course in theme.courses"
    :name="course.name"
    :key="course.id"
    ></project-card>
  </div>
</template>
<script>
import ProjectCard from "../components/ProjectCard.vue";

export default {
  inject: ["theme"],
  components: {
    ProjectCard,
  }
};
</script>

What is wrong with my code?

Upvotes: 1

Views: 1324

Answers (3)

user14967413
user14967413

Reputation: 1416

You are passing theme to the child component as injected property.

See Vue.js Docs:

The provide and inject bindings are NOT reactive. This is intentional. However, if you pass down an observed object, properties on that object do remain reactive.

As inject bindings are not reactive, the changed value of theme will not be visible from inside of the child component (it will stay the same as if no axios call happened).

Solution 1

Pass the value to the child component as an observed object. It means that in in your getTheme() method you will not rewrite the whole property value (this.theme = ...) but only write into the object which is already stored in the property (this.theme.themeData = ...).

data() {
  return {
    theme: { },
  };
},
provide() {
 return {
   theme: this.theme
 }
},
methods: {
  getTheme() {
    axios
      .get(here is my api url)
      .then((response) => (this.theme.themeData = response.data.data));
  },
},
mounted() {
  this.getTheme();
}

Solution 2

Alternatively you can pass the value to the child component using classical props which are always reactive.

Upvotes: 0

match
match

Reputation: 11060

When you set provide to 'handle' theme it adds reactivity to the value of theme - i.e the empty array ([]).

If you modify the elements in this array, it will remain reactive - however if you replace the array then the reactivity is broken.

Instead of overwriting theme in the axios call, try adding the resulting data to it. For example:

getTheme() {
  axios
    .get(here is my api url)
    .then((response) => (this.theme.push(...response.data.data));
}

Upvotes: 0

cafertayyar
cafertayyar

Reputation: 1072

Second option in the link may help you

provide() {
   return {
     $theme: () => this.theme,
   }
},

and

inject: ["$theme"],
computed: {
   computedProperty() {
      return this.$theme()
   }
}

and

v-for="course in computedProperty.courses"

Upvotes: 4

Related Questions