DEV Community

Discussion on: VueJS - Reusable Data Fetcher Component

Collapse
 
gmeral profile image
gmeral • Edited

Hi Pablo !
Thanks for the inspiration and the detailed article.
To me the biggest shortcoming of this implementation is that you do not control when the data is fetched (on your github repo, it is always done on created).

To circumvent this i thought about using a Promise as a prop instead of the apiMethods params and updater (this also makes the component simpler and much more flexible)

Then changing the promise props acts as a reload (or could eventually load something different, it is up to the user). The promise prop can also be omitted if the fetching has to occur later than the component creation (in response to a user action for example)

Here is how it would look like :

<template>
  <div>
    <div v-if="loading">
      Loading...
    </div>
    <div v-else-if="error">
      {{ error }}
    </div>
    <slot v-else :data="data" />
  </div>
</template>

<script>
export default {
  props: {
    promise: {
      type: Promise
    },
    initialValue: {
      type: [Number, String, Array, Object],
      default: null
    }
  },
  data() {
    return {
      loading: false,
      error: null,
      data: this.initialValue
    }
  },
  watch: {
    promise: {
      immediate: true,
      handler(newVal) {
        if(!newVal) return
        this.loading = true
        newVal
          .then(result => this.data = result)
          .catch(error => this.error = error)
          .finally(() => this.loading = false)
      }
    }
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
vcpablo profile image
Pablo Veiga

Hey @gmeral thanks for commenting. You are right, in the current implementation, the request will be executed each time the component is created.

Your suggestion is pretty good.
The only thing I'd do there is changing the promises callbacks to async/await

In my personal projects, I've done something similar to your implementation.
But I pass a boolean intermediate prop combined with a params watcher.
Like this:

created() {
    const { immediate } = this
    this.watcher = this.$watch('params', this.fetch, { immediate })
 }
Enter fullscreen mode Exit fullscreen mode

The difference is that this doesn't allow me to make different requests but the same one with different parameters.

I kind of don't see with good eyes scenarios where you might populate the same variable and context with different requests results, but it might happen.