2023-05-08 01:01:17 +00:00
|
|
|
<template>
|
2023-05-08 09:19:41 +00:00
|
|
|
<Cache
|
|
|
|
:name="props.cacheName"
|
|
|
|
:callback="fetchData"
|
2023-05-08 10:44:12 +00:00
|
|
|
:already-known-data="alreadyKnownData"
|
2023-05-08 09:19:41 +00:00
|
|
|
@cached="processCachedData"
|
|
|
|
/>
|
2023-05-08 01:34:48 +00:00
|
|
|
<slot v-if="loading" name="loader">
|
|
|
|
<Loader />
|
|
|
|
</slot>
|
2023-05-08 16:04:30 +00:00
|
|
|
<slot v-else-if="error" name="error">
|
|
|
|
<Error :url="props.url" />
|
2023-05-08 01:01:17 +00:00
|
|
|
</slot>
|
2023-05-08 16:04:30 +00:00
|
|
|
<slot v-else> </slot>
|
2023-05-08 01:01:17 +00:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
import Cache from './Cache.vue';
|
2023-05-08 01:34:48 +00:00
|
|
|
import Loader from './Loader.vue';
|
2023-05-08 16:04:30 +00:00
|
|
|
import Error from './Error.vue';
|
2023-05-08 01:01:17 +00:00
|
|
|
|
|
|
|
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,
|
|
|
|
},
|
2023-05-08 09:19:41 +00:00
|
|
|
cacheName: {
|
|
|
|
required: true,
|
|
|
|
type: String,
|
|
|
|
},
|
|
|
|
alreadyKnownData: Object,
|
2023-05-08 01:01:17 +00:00
|
|
|
});
|
|
|
|
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()),
|
2023-05-08 16:04:30 +00:00
|
|
|
catchError((errorResponse: Error) => {
|
|
|
|
error.value = errorResponse;
|
|
|
|
return Error;
|
2023-05-08 01:01:17 +00:00
|
|
|
})
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
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>
|