Search code examples
javascriptvue.jsprop

How can I add remote json data to prop?


I have the following code below that gets JSON data from a remote service and feeds it into a variable that should later also feed it into a prop. After which i manipulate the items in the prop. Ofcourse i got a Vue Error when trying to mutate the prop.

Here is the code:

<script>
import axios from 'axios'
import { API_BASE_URL } from '../config'

export default {
  props: {
    items: {
      type: Array,
      required: false,
      default: () => []
    }
  },
  data() {
    return {
      isLoading: true,
      novels: [],
      search: "",
      isOpen: false,
      arrowCounter: 0
    }
  },
  created() {
    axios.get(API_BASE_URL + '/novels').then(response => {
      this.novels = response.data.data
    })
    // this.items = this.novels
    this.isLoading = false
  },
  methods: {
    getNovel(novel){
      this.$router.push({ path: `novel/${novel.id}`})
      // this.$router.go(1)
    },

    onChange(){
      // Let's warn the parent that a change was made
      this.$emit("input", this.search);

      // Let's search our flat array
      this.filterResults();
      this.isOpen = true
    },

    filterResults() {
      // first uncapitalize all the things
      this.novels = this.items.filter(item => {
        return item.toLowerCase().indexOf(this.search.toLowerCase()) > -1;
      });
    }
}
</script>

Solution

  • So from this code, If you need to get the data from API on "Create" hook, there are three possible solutions,

    1. you should not define items as a prop but instead in data.

    OR

    1. If you really need items as a prop, you should make this API Call inside parent of this component and then pass the response data in items prop

    OR

    1. with this code, you can pass a method to the component and this component can emit that method with the new data. and that method in parent can update the items array. example is given below

      <this-component :items="items" @apiResponse="(newData) => items = newData" />

    and inside this component

    created() {
        axios.get(API_BASE_URL + '/novels').then(response => {
          this.novels = response.data.data
        })
        this.$emit('apiResponse', this.novels)
        this.isLoading = false
      },