++ If press DELETE or BACKSPACE and is blank description, delete the Todos.

- fix: if offline, doesn't save to cache??  if I refresh page, the data disappear
- ++ field to the percent progress
- fix: Refreshing 2 times the array todos.. because there is a filter
This commit is contained in:
Paolo Arena
2019-02-12 19:09:43 +01:00
parent a024b78e95
commit 259e2dc4e2
17 changed files with 252 additions and 188 deletions

View File

@@ -6,7 +6,7 @@
// Questo è il swSrc
console.log(' [ VER-0.0.21 ] _---------________-----------_________------------__________________________ PAO: this is my custom service worker');
console.log(' [ VER-0.0.21 ] _---------________------ PAO: this is my custom service worker');
importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.0.0/workbox-sw.js'); //++Todo: Replace with local workbox.js
importScripts('../statics/js/idb.js');
@@ -31,7 +31,7 @@ async function readAllData(table) {
}
async function clearAllData(table) {
console.log('clearAllData', table);
// console.log('clearAllData', table);
await idbKeyval.clearalldata(table)
}
@@ -108,9 +108,9 @@ if (workbox) {
return fetch(args.event.request, args.event.headers)
.then(function (res) {
myres = res
console.log('1° ******* [[[ SERVICE-WORKER ]]] registerRoute fetch: -> ', args.event.request, res)
// console.log('1° ******* [[[ SERVICE-WORKER ]]] registerRoute fetch: -> ', args.event.request, res)
// LOAD FROM SERVER , AND SAVE INTO INDEXEDDB
console.log('res.status', res.status)
// console.log('res.status', res.status)
if (res.status === 200) {
const clonedRes = res.clone();
clearAllData('todos')
@@ -333,82 +333,83 @@ if ('serviceWorker' in navigator) {
// });
self.addEventListener('sync', function (event) {
console.log('[Service Worker V5] Background syncing', event.tag);
let mystrparam = event.tag
let multiparams = mystrparam.split('|')
if (multiparams) {
if (multiparams.length > 3) {
let cmd = multiparams[0]
let table = multiparams[1]
let method = multiparams[2]
let token = multiparams[3]
// let lang = multiparams[3]
if (cmd === 'sync-todos') {
console.log('[Service Worker] Syncing', cmd, table, method);
const headers = new Headers()
headers.append('content-Type', 'application/json')
headers.append('Accept', 'application/json')
headers.append('x-auth', token)
// console.log('A1) INIZIO.............................................................');
event.waitUntil(
readAllData(table)
.then(function (alldata) {
const myrecs = [...alldata]
console.log('----------------------- LEGGO QUALCOSA DAL WAITUNTIL ')
if (myrecs) {
for (let rec of myrecs) {
//console.log('syncing', table, '', rec.descr)
let link = cfgenv.serverweb + '/todos'
if (method !== 'POST')
link += '/' + rec._id
console.log('++++++++++++++++++ SYNCING !!!! ', rec.descr, table, 'FETCH: ', method, link, 'data:')
// console.log('DATATOSAVE:', JSON.stringify(rec))
// Insert/Delete/Update table to the server
fetch(link, {
method: method,
headers: headers,
mode: 'cors', // 'no-cors',
body: JSON.stringify(rec)
})
.then(() => {
deleteItemFromData(table, rec._id)
deleteItemFromData('swmsg', mystrparam)
// console.log('config WRITE ONLINE')
writeData('config', { _id: 2, stateconn: 'online' })
})
.catch(function (err) {
console.log('err', err, err.message)
// console.log('DELETE : ', table, mystrparam)
if (err.message === 'Failed to fetch') {
// console.log('config WRITE OFFLINE')
writeData('config', { _id: 2, stateconn: 'offline' })
}
console.log('!!!!!!!!!!!!!!! Error while sending data', err);
})
}
}
})
);
// console.log('A2) ?????????????????????????? ESCO DAL LOOP !!!!!!!!! err=')
}
}
}
})
;
// self.addEventListener('sync', function (event) {
// console.log('[Service Worker V5] Background syncing', event.tag);
//
// let mystrparam = event.tag
// let multiparams = mystrparam.split('|')
// if (multiparams) {
// if (multiparams.length > 3) {
// let cmd = multiparams[0]
// let table = multiparams[1]
// let method = multiparams[2]
// let token = multiparams[3]
// // let lang = multiparams[3]
//
// if (cmd === 'sync-todos') {
// console.log('[Service Worker] Syncing', cmd, table, method);
//
// const headers = new Headers()
// headers.append('content-Type', 'application/json')
// headers.append('Accept', 'application/json')
// headers.append('x-auth', token)
//
//
// // console.log('A1) INIZIO.............................................................');
//
// event.waitUntil(
// readAllData(table)
// .then(function (alldata) {
// const myrecs = [...alldata]
// console.log('----------------------- LEGGO QUALCOSA DAL WAITUNTIL ')
// let errorfromserver = false
// if (myrecs) {
// for (let rec of myrecs) {
// //console.log('syncing', table, '', rec.descr)
// let link = cfgenv.serverweb + '/todos'
//
// if (method !== 'POST')
// link += '/' + rec._id
//
// console.log('++++++++++++++++++ SYNCING !!!! ', rec.descr, table, 'FETCH: ', method, link, 'data:')
//
// // console.log('DATATOSAVE:', JSON.stringify(rec))
//
// // Insert/Delete/Update table to the server
// fetch(link, {
// method: method,
// headers: headers,
// cache: 'no-cache',
// mode: 'cors', // 'no-cors',
// body: JSON.stringify(rec)
// })
// .then(() => {
// deleteItemFromData(table, rec._id)
// })
// .then(() => {
// deleteItemFromData('swmsg', mystrparam)
// })
// .catch(function (err) {
// console.log('!!!!!!!!!!!!!!! Error while sending data', err, err.message);
// if (err.message === 'Failed to fetch') {
// errorfromserver = true
// }
// })
// }
// return errorfromserver
// }
// })
// .then((errorfromserver) => {
// const mystate = !errorfromserver ? 'online' : 'offline'
// writeData('config', { _id: 2, stateconn: mystate })
// })
// );
// // console.log('A2) ?????????????????????????? ESCO DAL LOOP !!!!!!!!! err=')
// }
// }
// }
// })
// ;
/*

View File

@@ -191,16 +191,16 @@
console.log('Event LOAD')
if (window) {
window.addEventListener('load', function () {
console.log('2) ENTERING Event LOAD')
// console.log('2) ENTERING Event LOAD')
function updateOnlineStatus(event) {
if (navigator.onLine) {
console.log('EVENT ONLINE!')
// console.log('EVENT ONLINE!')
// handle online status
GlobalStore.mutations.setStateConnection('online')
mythis.changeIconConn()
} else {
console.log('EVENT OFFLINE!')
// console.log('EVENT OFFLINE!')
// handle offline status
GlobalStore.mutations.setStateConnection('offline')
mythis.changeIconConn()

View File

@@ -264,6 +264,15 @@ export default class SingleTodo extends Vue {
}
}
*/
if (((e.keyCode === 8) || (e.keyCode === 46)) && (this.precDescr === '') && !e.shiftKey) {
e.preventDefault()
this.clickMenu(rescodes.MenuAction.DELETE)
.then(() => {
this.deselectRiga()
this.faiFocus('insertTask', true)
return
})
}
if (((e.key === 'Enter') || (e.key === 'Tab')) && !e.shiftKey) {
this.updateTodo()
@@ -344,16 +353,16 @@ export default class SingleTodo extends Vue {
}
clickMenu(action) {
async clickMenu(action) {
console.log('click menu: ', action)
if (action === rescodes.MenuAction.DELETE) {
this.askConfirmDelete()
return this.askConfirmDelete()
} else if (action === rescodes.MenuAction.TOGGLE_EXPIRING) {
this.enableExpiring()
return this.enableExpiring()
} else if (action === rescodes.MenuAction.COMPLETED) {
this.setCompleted()
return this.setCompleted()
} else if (action === rescodes.MenuAction.PROGRESS_BAR) {
this.updatedata()
return this.updatedata()
}
}
@@ -369,11 +378,11 @@ export default class SingleTodo extends Vue {
// this.$q.notify('setPriority: ' + elem)
}
askConfirmDelete() {
async askConfirmDelete() {
const deletestr = this.$t('dialog.delete')
const cancelstr = this.$t('dialog.cancel')
askConfirm(this.$q, this.$t('dialog.msg.titledeleteTask'), this.$t('dialog.msg.deleteTask').toString(), deletestr, cancelstr)
await askConfirm(this.$q, this.$t('dialog.msg.titledeleteTask'), this.$t('dialog.msg.deleteTask').toString(), deletestr, cancelstr)
.then(ris => {
console.log('ris', ris)
if (ris)

View File

@@ -23,7 +23,7 @@
</q-btn>
</div>
<q-input type="textarea" ref="inputdescr" v-model="precDescr"
<q-input type="textarea" ref="inputdescr" v-model.trim="precDescr"
:class="classDescr" :max-height="50"
@keydown="keyDownArea" v-on:keydown.esc="exitEdit" @blur="exitEdit(true)" @click="editTodo()"/>
@@ -33,7 +33,7 @@
<!--<q-field>{{ itemtodo.descr }}</q-field>-->
<!--</div>-->
<div v-if="isTodo()" class="flex-item progress-item">
<div v-if="isTodo() && (percentageProgress > 0) " class="flex-item progress-item">
<q-progress
:percentage="percentageProgress"
class="progress-item"

View File

@@ -3,7 +3,7 @@
}
.item-menu{
.item-menu {
font-size: 1rem;
}
@@ -11,6 +11,7 @@
cursor: pointer;
}
.menuProgress {
.menuInputProgress > div:nth-child(2) > div > input {
min-width: 30px;
width: 30px;
}

View File

@@ -2,8 +2,8 @@ import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'
import { ITodo } from '../../../model/index'
import { rescodes } from "@src/store/Modules/rescodes"
import { UserStore } from "@store"
import { rescodes } from '@src/store/Modules/rescodes'
import { UserStore } from '@store'
@Component({
@@ -14,7 +14,7 @@ export default class SubMenus extends Vue {
public selectPriority: [] = rescodes.selectPriority[UserStore.state.lang]
@Prop({ required: false }) menuPopupTodo: any[]
@Prop({ required: false }) itemtodo: ITodo[]
@Prop({ required: false }) itemtodo: ITodo
$q: any
clickMenu (field) {
@@ -25,6 +25,15 @@ export default class SubMenus extends Vue {
this.$emit('setPriority', field)
}
KeychangeProgress (e) {
if (this.itemtodo.progress > 100) {
this.itemtodo.progress = 100
}
if (this.itemtodo.progress < 0) {
this.itemtodo.progress = 0
}
}
create () {
this.selectPriority = rescodes.selectPriority[UserStore.state.lang]

View File

@@ -18,14 +18,28 @@
</q-item-side>
<q-item-main v-if="field.value === 120">
<q-slider :class="$parent.menuProgress" v-model="itemtodo.progress" :min="0" :max="100"/>
<q-slider :class="$parent.menuProgress" v-model="itemtodo.progress" :min="0" :max="100"
:step="5"/>
</q-item-main>
<q-item-side v-if="field.value === 120">
<div :class="$parent.percProgress">
{{$parent.percentageProgress}}%
<q-item-side v-if="field.value === 120" >
<div>
<q-input v-model="itemtodo.progress"
class="menuInputProgress"
type="number"
suffix="%"
@change="val => { model = val }"
@keydown="KeychangeProgress"
/>
</div>
</q-item-side>
<!--<q-item-side right v-if="field.value === 120">-->
<!--<div :class="$parent.percProgress">-->
<!--{{$parent.percentageProgress}}%-->
<!--</div>-->
<!--</q-item-side>-->
</q-item>
<q-item v-if="(field.value === 100)" :icon="field.icon" v-close-overlay
@click.native="clickMenu(field.value)">
@@ -61,6 +75,6 @@
<script lang="ts" src="./SubMenus.ts">
</script>
<style lang="scss" scoped>
<style lang="scss">
@import './SubMenus.scss';
</style>

View File

@@ -43,6 +43,7 @@ export default class Todo extends Vue {
itemDragEnd: any = null
selrowid: number = 0
polling = null
mytypetransgroup: string = 'crossfade'
fieldtochange: String [] = ['descr', 'completed', 'category', 'expiring_at', 'priority', 'id_prev', 'id_next', 'pos', 'enableExpiring', 'progress']
@@ -65,7 +66,10 @@ export default class Todo extends Vue {
@Watch('$route.params.category') changecat() {
// console.log('changecat')
this.load()
this.mytypetransgroup = 'nessuno'
this.updatetable().then(() => {
this.mytypetransgroup = 'crossfade'
})
}
get todos_changed() {
@@ -82,7 +86,7 @@ export default class Todo extends Vue {
// this.$q.notify('Changed...')
// console.log('Todos.state.todos_changed CHANGED!', value, oldValue)
console.log('Todos.state.todos_changed CHANGED!', value, oldValue)
this.updatetable(true)
}
@@ -600,12 +604,16 @@ export default class Todo extends Vue {
}
async updatetable(refresh: boolean = false) {
// console.log('updatetable')
console.log('updatetable')
this.prevRecords = [...this.todos_arr]
return await Todos.actions.getTodosByCategory(this.getCategory())
.then(arrtemp => {
.then(arrris => {
this.todos_arr = []
let arrtemp = [...arrris]
arrtemp = _.orderBy(arrtemp, ['completed', 'priority', 'pos'], ['asc', 'desc', 'asc'])
@@ -620,6 +628,8 @@ export default class Todo extends Vue {
this.todos_arr = [...arrtemp] // make copy
console.log('AGGIORNA todos_arr')
})
}

View File

@@ -12,7 +12,7 @@
<div class="drag">
<draggable v-model="todos_arr" :options="{draggable:'.myitemdrag'}"
@start="onStart" @end="onEnd" class="dragArea">
<transition-group>
<transition-group :name="mytypetransgroup" >
<div :id="getmyid(mytodo._id)" :key="mytodo._id" v-for="mytodo in todos_arr" class="myitemdrag">
<div v-if="(prior !== mytodo.priority) && !mytodo.completed" :class="getTitlePriority(mytodo.priority)">

View File

@@ -86,7 +86,7 @@ export let idbKeyval = (() => {
async setdata(table, value) {
let req;
console.log('setdata', table, value)
// console.log('setdata', table, value)
await withStore('readwrite', table, store => {
req = store.put(value);
});
@@ -103,7 +103,7 @@ export let idbKeyval = (() => {
});
},
async clearalldata(table) {
console.log('clearalldata', table)
// console.log('clearalldata', table)
return await withStore('readwrite', table, store => {
store.clear();
});

View File

@@ -105,7 +105,7 @@ let idbKeyval = (() => {
});
},
async clearalldata(table) {
console.log('clearalldata', table)
// console.log('clearalldata', table)
return await withStore('readwrite', table, store => {
store.clear();
});

View File

@@ -9,7 +9,7 @@ async function sendRequest(url: string, lang: string, mytok: string, method: str
authHeader.append('Accept', 'application/json')
if (url !== process.env.MONGODB_HOST + '/users/login') {
authHeader.append('x-auth', mytok)
console.log('TOK PASSATO ALLA FETCH:', mytok)
// console.log('TOK PASSATO ALLA FETCH:', mytok)
}
// authHeader.append('accept-language', lang)

View File

@@ -55,11 +55,11 @@ export namespace ApiTool {
return sendRequest(url, UserStore.state.lang, UserStore.state.x_auth_token, method, mydata)
.then(resreceived => {
console.log('resreceived', resreceived)
// console.log('resreceived', resreceived)
ricevuto = true
let res = resreceived.clone()
if (process.env.DEV) {
console.log('SendReq RES [', res.status, ']', res)
// console.log('SendReq RES [', res.status, ']', res)
}
UserStore.mutations.setResStatus(res.status)
@@ -143,66 +143,73 @@ export namespace ApiTool {
// let lang = multiparams[3]
if (cmd === 'sync-todos') {
console.log('[Alternative] Syncing', cmd, table, method)
// console.log('[Alternative] Syncing', cmd, table, method)
const headers = new Headers()
headers.append('content-Type', 'application/json')
headers.append('Accept', 'application/json')
headers.append('x-auth', token)
let errorfromserver = false
let lettoqualcosa = false
// console.log('A1) INIZIO.............................................................')
await globalroutines(null, 'readall', table, null)
globalroutines(null, 'readall', table, null)
.then(function (alldata) {
const myrecs = [...alldata]
// console.log('----------------------- LEGGO QUALCOSA ')
if (myrecs) {
for (let rec of myrecs) {
// console.log('syncing', table, '', rec.descr)
let link = process.env.MONGODB_HOST + '/todos'
const myrecs = [...alldata]
// console.log('----------------------- LEGGO QUALCOSA ')
if (method !== 'POST')
link += '/' + rec._id
const promises = myrecs.map(rec => {
// console.log('syncing', table, '', rec.descr)
let link = process.env.MONGODB_HOST + '/todos'
console.log(' [Alternative] ++++++++++++++++++ SYNCING !!!! ', rec.descr, table, 'FETCH: ', method, link, 'data:')
if (method !== 'POST')
link += '/' + rec._id
let lettoqualcosa = false
// console.log(' [Alternative] ++++++++++++++++++ SYNCING !!!! ', rec.descr, table, 'FETCH: ', method, link, 'data:')
// Insert/Delete/Update table to the server
fetch(link, {
method: method,
headers: headers,
cache: 'no-cache',
mode: 'cors', // 'no-cors',
body: JSON.stringify(rec)
}).then(resData => {
lettoqualcosa = true
// Insert/Delete/Update table to the server
return fetch(link, {
method: method,
headers: headers,
cache: 'no-cache',
mode: 'cors', // 'no-cors',
body: JSON.stringify(rec)
})
.then(() => {
globalroutines(null, 'delete', table, null, rec._id)
lettoqualcosa = true
})
.then(() => {
globalroutines(null, 'delete', 'swmsg', null, mystrparam)
})
.catch(function (err) {
if (err.message === 'Failed to fetch') {
errorfromserver = true
}
// console.log(' [Alternative] !!!!!!!!!!!!!!! Error while sending data', err, errorfromserver, 'lettoqualcosa', lettoqualcosa)
})
})
return globalroutines(null, 'delete', 'swmsg', null, mystrparam)
}).then(() => globalroutines(null, 'delete', table, null, rec._id))
.then((ris) => {
return globalroutines(null, 'write', 'config', { _id: 2, stateconn: 'online' })
})
.then(() => {
// console.log('Clear', 'swmsg', method)
GlobalStore.mutations.setStateConnection(lettoqualcosa ? 'online' : 'offline')
})
.catch(function (err) {
if (err.message === 'Failed to fetch') {
// console.log('config WRITE OFFLINE')
globalroutines(null, 'write', 'config', { _id: 2, stateconn: 'offline' })
}
console.log(' [Alternative] !!!!!!!!!!!!!!! Error while sending data', err)
GlobalStore.mutations.setStateConnection(lettoqualcosa ? 'online' : 'offline')
})
// CALL ALL THE PROMISES
return Promise.all(promises).then(() => {
return (errorfromserver && !lettoqualcosa)
}).catch(err => {
return (errorfromserver && !lettoqualcosa)
})
}
}
}
).catch(e => {
console.log('ERROR:', e)
}).catch(e => {
// console.log('ERROR:', e)
return (errorfromserver && !lettoqualcosa)
})
.then((errorfromserver) => {
// console.log('¨¨¨¨¨¨¨¨¨¨¨¨¨¨ errorfromserver:', errorfromserver)
const mystate = errorfromserver ? 'offline' : 'online'
globalroutines(null, 'write', 'config', { _id: 2, stateconn: mystate })
GlobalStore.mutations.setStateConnection(mystate)
})
console.log(' [Alternative] A2) ?????????????????????????? ESCO DAL LOOP !!!!!!!!! err=')
// console.log(' [Alternative] A2) ?????????????????????????? ESCO DAL LOOP !!!!!!!!!')
}
}

View File

@@ -135,7 +135,7 @@ namespace Actions {
mystate.isSubscribed = !(subscription === null)
if (mystate.isSubscribed) {
console.log('User is already Subscribed!')
// console.log('User is already Subscribed!')
} else {
// Create a new subscription
let convertedVapidPublicKey = urlBase64ToUint8Array(mykey)

View File

@@ -43,7 +43,7 @@ namespace Mutations {
function setTodos_changed(state: ITodosState) {
state.todos_changed++
mutations.setTestpao('Cambiato : ' + String(state.todos_changed))
console.log('******************************* state.todos_changed', state.todos_changed)
console.log('******* state.todos_changed', state.todos_changed)
}
export const mutations = {
@@ -195,16 +195,16 @@ namespace Actions {
state.networkDataReceived = false
let ris = await Api.SendReq(call, 'GET', null)
.then(({ resData, body, status }) => {
.then(({ res, body, status }) => {
state.networkDataReceived = true
// console.log('******* UPDATE TODOS.STATE.TODOS !:', resData.todos)
// console.log('******* UPDATE TODOS.STATE.TODOS !:', res.todos)
if (body.todos) {
state.todos = [...body.todos]
Todos.mutations.setTodos_changed()
}
console.log('********** resData', resData, 'state.todos', state.todos, 'checkPending', checkPending)
console.log('********** res', res, 'state.todos', state.todos, 'checkPending', checkPending)
// After Login will store into the indexedDb...
@@ -216,8 +216,8 @@ namespace Actions {
return { status }
})
console.log('ris : ', ris)
console.log('ris STATUS: ', ris.status)
// console.log('ris : ', ris)
// console.log('ris STATUS: ', ris.status)
if (!Todos.state.networkDataReceived) {

View File

@@ -111,7 +111,7 @@ namespace Mutations {
if (!state.tokens) {
state.tokens = []
}
state.tokens.push({ access: 'auth ' + navigator.userAgent, token: data.x_auth_token, data_login: new Date() })
state.tokens.push({ access: 'auth ' + navigator.userAgent, token: data.x_auth_token, data_login: new Date() })
}
function setServerCode(state: IUserState, num: number) {
@@ -227,7 +227,7 @@ namespace Actions {
})
.catch((error) => {
UserStore.mutations.setErrorCatch(error)
return UserStore.getters.getServerCode
return { code: UserStore.getters.getServerCode, msg: error }
})
}
@@ -366,7 +366,7 @@ namespace Actions {
console.log('MYLANG = ' + state.lang)
await navigator.serviceWorker.ready
return await navigator.serviceWorker.ready
.then(function (swreg) {
const sub = swreg.pushManager.getSubscription()
return sub
@@ -408,7 +408,26 @@ namespace Actions {
Mutations.mutations.setServerCode(myres.status)
if (myres.status === 200) {
if (myres.status !== 200) {
return Promise.reject(rescodes.ERR_GENERICO)
}
return { res, body }
}).then(({ res, body }) => {
if (myres.status === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN) {
if (process.env.DEV) {
console.log('CODE = ' + body.code)
}
return body.code
} else if (res.status !== 200) {
if (process.env.DEV) {
console.log('CODE = ' + body.code)
}
return body.code
}
if (res.status === 200) {
let myuser: IUserState = body.usertosend
if (myuser) {
let userId = myuser.userId
@@ -436,24 +455,19 @@ namespace Actions {
localStorage.setItem(rescodes.localStorage.isLogged, String(true))
localStorage.setItem(rescodes.localStorage.verified_email, String(verified_email))
setGlobal(true)
}
}
// dispatch('storeUser', authData);
// dispatch('setLogoutTimer', myres.data.expiresIn);
return rescodes.OK
} else {
return rescodes.ERR_GENERICO
}
} else if (myres.status === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN) {
if (process.env.DEV) {
console.log('CODE = ' + body.code)
}
return body.code
return rescodes.OK
}).then(code => {
if (code === rescodes.OK) {
return setGlobal(true)
.then(() => {
return code
})
} else {
if (process.env.DEV) {
console.log('CODE = ' + body.code)
}
return body.code
return code
}
})
.catch((error) => {
@@ -507,7 +521,6 @@ namespace Actions {
GlobalStore.mutations.setCategorySel(localStorage.getItem(rescodes.localStorage.categorySel))
await GlobalStore.actions.loadAfterLogin()
.then(() => {
Todos.actions.dbLoadTodo(true)

View File

@@ -104,8 +104,8 @@
if (ris.code === serv_constants.RIS_CODE_OK)
this.emailsent = true;
this.$q.loading.hide();
}).catch(error => {
console.log("ERROR = " + error);
}).catch(err => {
console.log("ERROR = " + err.error);
this.$q.loading.hide();
});