feat: handle API calls and caching through Vue components
BREAKING CHANGE: API calls and cache no longer made in their respective composable
This commit is contained in:
53
content/.vuepress/components/ApiLoader.vue
Normal file
53
content/.vuepress/components/ApiLoader.vue
Normal file
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<Cache name="repos" :callback="fetchData" @cached="processCachedData" />
|
||||
<slot v-if="loading" name="loader"></slot>
|
||||
<slot v-else-if="error" name="error"></slot>
|
||||
<slot v-else>
|
||||
{{ error }}
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Cache from './Cache.vue';
|
||||
|
||||
import { Ref, ref } from 'vue';
|
||||
import { Observable, catchError, switchMap, throwError } from 'rxjs';
|
||||
import { fromFetch } from 'rxjs/fetch';
|
||||
|
||||
const props = defineProps({
|
||||
url: {
|
||||
default: false,
|
||||
required: true,
|
||||
type: String,
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(['dataLoaded', 'dataError', 'loading']);
|
||||
|
||||
const error: Ref<Error> = ref(null);
|
||||
const loading: Ref<boolean> = ref(true);
|
||||
|
||||
const fetchData = (): Observable<any> => {
|
||||
return fromFetch(props.url).pipe(
|
||||
switchMap((response: Response) => response.json()),
|
||||
catchError((error: Error) => {
|
||||
console.error(error);
|
||||
return throwError(() => new Error(error.message));
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const processCachedData = (data: Observable<any>) => {
|
||||
data.subscribe({
|
||||
next: (response: any) => {
|
||||
loading.value = false;
|
||||
emits('dataLoaded', response);
|
||||
},
|
||||
error: (responseError: Error) => {
|
||||
loading.value = false;
|
||||
error.value = responseError;
|
||||
},
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less"></style>
|
||||
Reference in New Issue
Block a user