Move everything to models and services #17
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="loader-container" :class="{ 'is-loading': loading}">
|
||||
<div class="loader-container" :class="{ 'is-loading': listService.loading}">
|
||||
<div class="content">
|
||||
<router-link :to="{ name: 'editList', params: { id: list.id } }" class="icon settings is-medium">
|
||||
<icon icon="cog" size="2x"/>
|
||||
|
@ -213,6 +213,7 @@
|
|||
data() {
|
||||
return {
|
||||
listID: this.$route.params.id,
|
||||
listService: ListService,
|
||||
list: {},
|
||||
newTask: {text: ''},
|
||||
error: '',
|
||||
|
@ -244,6 +245,7 @@
|
|||
}
|
||||
},
|
||||
created() {
|
||||
this.listService = new ListService()
|
||||
this.loadList()
|
||||
},
|
||||
watch: {
|
||||
|
@ -255,13 +257,12 @@
|
|||
this.isTaskEdit = false
|
||||
//const cancel = message.setLoading(this)
|
||||
|
||||
let listService = new ListService()
|
||||
listService.get({id: this.$route.params.id}, {})
|
||||
this.listService.get({id: this.$route.params.id}, {})
|
||||
.then(r => {
|
||||
this.$set(this, 'list', r)
|
||||
})
|
||||
.catch(e => {
|
||||
this.handleError(e)
|
||||
message.error(e, this)
|
||||
})
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,13 +1,20 @@
|
|||
import {defaults, omitBy, isNil} from "lodash";
|
||||
import {defaults, omitBy, isNil} from 'lodash'
|
||||
|
||||
export default class AbstractModel {
|
||||
|
||||
|
||||
/**
|
||||
* The abstract constructor takes an object and merges its data with the default data of this model.
|
||||
* @param data
|
||||
*/
|
||||
constructor(data) {
|
||||
// Put all data in our model while overriding those with a value of null or undefined with their defaults
|
||||
defaults(this, omitBy(data, isNil), this.defaults())
|
||||
}
|
||||
|
||||
// Default attributes that define the "empty" state.
|
||||
|
||||
/**
|
||||
* Default attributes that define the "empty" state.
|
||||
* @return {{}}
|
||||
*/
|
||||
defaults() {
|
||||
return {}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import abstractModel from "./abstractModel";
|
||||
import AbstractModel from './abstractModel'
|
||||
|
||||
export default class ListModel extends abstractModel {
|
||||
export default class ListModel extends AbstractModel {
|
||||
|
||||
constructor(data) {
|
||||
super(data)
|
||||
this.sortTasks()
|
||||
|
||||
// TODO: fixStuffComingFromAPI (see ShowList.vue)
|
||||
}
|
||||
|
||||
// Default attributes that define the "empty" state.
|
||||
|
@ -21,7 +23,9 @@ export default class ListModel extends abstractModel {
|
|||
updated: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////
|
||||
// Helpers
|
||||
sortTasks() {
|
||||
if (this.tasks === null || this.tasks === []) {
|
||||
return
|
||||
|
|
|
@ -4,17 +4,25 @@ import {reduce, replace} from 'lodash'
|
|||
let config = require('../../public/config.json')
|
||||
|
||||
export default class AbstractService {
|
||||
|
||||
/////////////////////////////
|
||||
// Initial variable definitions
|
||||
http = null
|
||||
loading = false
|
||||
paths = {
|
||||
create: '',
|
||||
get: '',
|
||||
update: '',
|
||||
delete: '',
|
||||
}
|
||||
///////////////////////////////////////
|
||||
// SERVICE INIT
|
||||
///////////////////////////////////////
|
||||
|
||||
|
||||
/////////////
|
||||
// Service init
|
||||
|
||||
/**
|
||||
* The abstract constructor.
|
||||
* @param paths An object with all paths. Default values are specified above.
|
||||
*/
|
||||
constructor(paths) {
|
||||
this.http = axios.create({
|
||||
baseURL: config.VIKUNJA_API_BASE_URL,
|
||||
|
@ -37,78 +45,103 @@ export default class AbstractService {
|
|||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// GLOBAL ERROR HANDLER
|
||||
///////////////////////////////////////
|
||||
/////////////////////
|
||||
// Global error handler
|
||||
|
||||
/**
|
||||
* Handles the error and rejects the promise.
|
||||
* @param url
|
||||
* @param error
|
||||
* @returns {Promise<never>}
|
||||
*/
|
||||
errorHandler(url, error) {
|
||||
// eslint-disable-next-line
|
||||
console.log('[Err][GET][%s] %o', url, error);
|
||||
if (error.response) {
|
||||
return Promise.reject({response: error});
|
||||
} else if (error.request) {
|
||||
return Promise.reject({request: error});
|
||||
} else {
|
||||
return Promise.reject({message: error});
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
// Helper functions //
|
||||
//////////////////////
|
||||
|
||||
/////////////////
|
||||
// Helper functions
|
||||
|
||||
/**
|
||||
* Returns an object with all route parameters and their values.
|
||||
* @param route
|
||||
* @returns object
|
||||
*/
|
||||
getRouteReplacements(route) {
|
||||
var parameters = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
var replace$$1 = {};
|
||||
var pattern = this.getRouteParameterPattern();
|
||||
pattern = new RegExp(pattern instanceof RegExp ? pattern.source : pattern, 'g');
|
||||
|
||||
for (var parameter; (parameter = pattern.exec(route)) !== null;) {
|
||||
let parameters = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}
|
||||
let replace$$1 = {}
|
||||
let pattern = this.getRouteParameterPattern()
|
||||
pattern = new RegExp(pattern instanceof RegExp ? pattern.source : pattern, 'g')
|
||||
|
||||
for (let parameter; (parameter = pattern.exec(route)) !== null;) {
|
||||
replace$$1[parameter[0]] = parameters[parameter[1]];
|
||||
}
|
||||
|
||||
|
||||
return replace$$1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Holds the replacement pattern for url paths, can be overwritten by implementations.
|
||||
* @return {RegExp}
|
||||
*/
|
||||
getRouteParameterPattern() {
|
||||
return /\{([^}]+)\}/
|
||||
return /{([^}]+)}/
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// GLOBAL ACTIONS
|
||||
///////////////////////////////////////
|
||||
|
||||
getData(pathparams, params) {
|
||||
|
||||
// parse the url
|
||||
let replacements = this.getRouteReplacements(this.paths.get, pathparams); // Replace all route parameters with their replacement values.
|
||||
|
||||
let replaced = reduce(replacements, function (result, value, parameter) {
|
||||
return replace(result, parameter, value);
|
||||
|
||||
/**
|
||||
* Returns a fully-ready-ready-to-make-a-request-to route with replaced parameters.
|
||||
* @param path
|
||||
* @param pathparams
|
||||
* @return string
|
||||
*/
|
||||
getReplacedRoute(path, pathparams) {
|
||||
let replacements = this.getRouteReplacements(path, pathparams)
|
||||
return reduce(replacements, function (result, value, parameter) {
|
||||
return replace(result, parameter, value)
|
||||
}, this.paths.get)
|
||||
|
||||
|
||||
// eslint-disable-next-line
|
||||
console.log('[Req][GET][%s] %o', this.paths.get, params, pathparams, replaced);
|
||||
return this.http.get(replaced, {params: params})
|
||||
}
|
||||
|
||||
/**
|
||||
* setLoading is a method which sets the loading variable to true, after a timeout of 100ms.
|
||||
* It has the timeout to prevent the loading indicator from showing for only a blink of an eye in the
|
||||
* case the api returns a response in < 100ms.
|
||||
* But because the timeout is created using setTimeout, it will still triggerm even if the request is
|
||||
* already finished, so we return a method to call in that case.
|
||||
* @returns {Function}
|
||||
*/
|
||||
setLoading() {
|
||||
const timeout = setTimeout(() => {
|
||||
this.loading = true
|
||||
}, 100)
|
||||
return () => {
|
||||
clearTimeout(timeout)
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
///////////////
|
||||
// Global actions
|
||||
|
||||
/**
|
||||
* Performs a get request to the url specified before.
|
||||
* @param pathparams The parameters inside of the url
|
||||
* @param params Extra query parameters
|
||||
* @returns {Q.Promise<any>}
|
||||
*/
|
||||
getData(pathparams, params) {
|
||||
|
||||
// We later will be able to cancel the loading indicator using this.
|
||||
const cancel = this.setLoading()
|
||||
|
||||
// Finally make the request and get our data.
|
||||
return this.http.get(this.getReplacedRoute(this.paths.get, pathparams), {params: params})
|
||||
.catch(error => {
|
||||
return this.errorHandler(this.paths.get, error);
|
||||
return this.errorHandler(this.paths.get, error)
|
||||
})
|
||||
.then(response => {
|
||||
// eslint-disable-next-line
|
||||
console.log('[Res][GET][%s] %o', this.paths.get, response);
|
||||
//if (Array.isArray(response.data)) {
|
||||
return Promise.resolve(response.data)
|
||||
/*}
|
||||
else {
|
||||
if (Array.isArray(response.data.content)) {
|
||||
const paginatedResponse = new PaginatedDomain();
|
||||
paginatedResponse.setDataFromHttpResponse(response);
|
||||
return Promise.resolve(paginatedResponse);
|
||||
}
|
||||
return Promise.resolve({...response.data});
|
||||
}*/
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
cancel()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
Reference in New Issue
Block a user