Vue Arbitrary data loader component
by Admiral Potato
HTML
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
<arbitrary-data-loader-component
@data="handleData('a', $event)"
default="https://jsonplaceholder.typicode.com/photos/1"
></arbitrary-data-loader-component>
<arbitrary-data-loader-component
@data="handleData('b', $event)"
default="https://raw.githubusercontent.com/fanzeyi/pokemon.json/master/pokedex.json"
></arbitrary-data-loader-component>
<h2>Current data A:</h2>
<pre>{{a}}</pre>
<h2>Current data B:</h2>
<pre>{{b}}</pre>
</div>
CSS
body {
font-family: sans-serif;
}
.isLoading {
color: #999;
}
.isParsing {
color: #99f;
}
.hasErrors {
color: #f00;
}
JavaScript
Vue.component('arbitrary-data-loader-component', {
props: {
default: {
type: String,
required: false
}
},
data: function() {
return {
isLoading: false,
isParsing: false,
hasErrors: false,
errorMessage: '',
sourceUrl: this.default || ''
}
},
computed: {
state: function() {
return JSON.stringify({
isLoading: this.isLoading,
isParsing: this.isParsing,
hasErrors: this.hasErrors,
errorMessage: this.errorMessage,
},
null,
'\t'
);
},
classes: function() {
return {
isLoading: this.isLoading,
isParsing: this.isParsing,
hasErrors: this.hasErrors,
};
}
},
methods: {
makeRequest: function() {
var self = this;
this.isLoading = true;
this.isParsing = false;
this.hasErrors = false;
this.errorMessage = '';
fetch(this.sourceUrl + "?random=" + Math.random())
.then(function(request) {
if (!request.ok) {
throw new Error('Remote asset load error')
}
return request.text()
.then(function (text) {
self.isParsing = true;
return new Promise(function (resolve, reject) {
setTimeout(
function () {
try {
resolve(JSON.parse(text));
} catch (e) {
reject(e);
}
},
0
)
})
})
})
.then(function(parsedJson) {
self.isParsing = false;
self.isLoading = false;
self.$emit('data', parsedJson);
})
.catch(function(error) {
self.isParsing = false;
self.isLoading = false;
self.hasErrors = true;
self.errorMessage = error.message;
});
},
},
template: /* html */ `
<div class="arbitrary-data-loader-component">
<h2>arbitrary data loader component</h2>
<pre
:class="classes"
>{{ state...