Refactor global API response handling in axios.
Instead of using a response transformer, move the global response JSON transformation (snake case to camel case) to the pre-existing response interceptor. Also, fix the `data.data` and `data` discrepancy in responses.
This commit is contained in:
parent
39aa56454e
commit
3df889cdc1
|
@ -9,22 +9,22 @@ const http = axios.create({
|
||||||
baseURL: process.env.BASE_URL,
|
baseURL: process.env.BASE_URL,
|
||||||
withCredentials: false,
|
withCredentials: false,
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
transformResponse: [
|
// transformResponse: [
|
||||||
// Apply the defaut transformations as well.
|
// // Apply the defaut transformations as well.
|
||||||
...axios.defaults.transformResponse,
|
// ...axios.defaults.transformResponse,
|
||||||
(resp) => {
|
// (resp) => {
|
||||||
if (!resp) {
|
// if (!resp) {
|
||||||
return resp;
|
// return resp;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// There's an error message.
|
// // There's an error message.
|
||||||
if ('message' in resp && resp.message !== '') {
|
// if ('message' in resp && resp.message !== '') {
|
||||||
return resp;
|
// return resp;
|
||||||
}
|
// }
|
||||||
|
|
||||||
return humps.camelizeKeys(resp.data);
|
// return humps.camelizeKeys(resp.data);
|
||||||
},
|
// },
|
||||||
],
|
// ],
|
||||||
|
|
||||||
// Override the default serializer to switch params from becoming []id=a&[]id=b ...
|
// Override the default serializer to switch params from becoming []id=a&[]id=b ...
|
||||||
// in GET and DELETE requests to id=a&id=b.
|
// in GET and DELETE requests to id=a&id=b.
|
||||||
|
@ -47,11 +47,21 @@ http.interceptors.response.use((resp) => {
|
||||||
store.commit('setLoading', { model: resp.config.loading, status: false });
|
store.commit('setLoading', { model: resp.config.loading, status: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let data = {};
|
||||||
|
if (resp.data && resp.data.data) {
|
||||||
|
if (typeof resp.data.data === 'object') {
|
||||||
|
data = humps.camelizeKeys(resp.data.data);
|
||||||
|
} else {
|
||||||
|
data = resp.data.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Store the API response for a model.
|
// Store the API response for a model.
|
||||||
if ('store' in resp.config) {
|
if ('store' in resp.config) {
|
||||||
store.commit('setModelResponse', { model: resp.config.store, data: resp.data });
|
store.commit('setModelResponse', { model: resp.config.store, data });
|
||||||
}
|
}
|
||||||
return resp;
|
|
||||||
|
return data;
|
||||||
}, (err) => {
|
}, (err) => {
|
||||||
// Clear the loading state for a model.
|
// Clear the loading state for a model.
|
||||||
if ('loading' in err.config) {
|
if ('loading' in err.config) {
|
||||||
|
|
|
@ -181,13 +181,13 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
getCampaign(id) {
|
getCampaign(id) {
|
||||||
return this.$api.getCampaign(id).then((r) => {
|
return this.$api.getCampaign(id).then((data) => {
|
||||||
this.data = r.data;
|
this.data = data;
|
||||||
this.form = { ...this.form, ...r.data };
|
this.form = { ...this.form, ...data };
|
||||||
|
|
||||||
if (r.data.sendAt !== null) {
|
if (data.sendAt !== null) {
|
||||||
this.form.sendLater = true;
|
this.form.sendLater = true;
|
||||||
this.form.sendAtDate = dayjs(r.data.sendAt).toDate();
|
this.form.sendAtDate = dayjs(data.sendAt).toDate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -236,13 +236,8 @@ export default Vue.extend({
|
||||||
// body: this.form.body,
|
// body: this.form.body,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$api.createCampaign(data).then((r) => {
|
this.$api.createCampaign(data).then((d) => {
|
||||||
this.$router.push({ name: 'campaign', hash: '#content', params: { id: r.data.id } });
|
this.$router.push({ name: 'campaign', hash: '#content', params: { id: d.id } });
|
||||||
|
|
||||||
// this.data = r.data;
|
|
||||||
// this.isEditing = true;
|
|
||||||
// this.isNew = false;
|
|
||||||
// this.activeTab = 1;
|
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
@ -270,10 +265,10 @@ export default Vue.extend({
|
||||||
|
|
||||||
// This promise is used by startCampaign to first save before starting.
|
// This promise is used by startCampaign to first save before starting.
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
this.$api.updateCampaign(this.data.id, data).then((resp) => {
|
this.$api.updateCampaign(this.data.id, data).then((d) => {
|
||||||
this.data = resp.data;
|
this.data = d;
|
||||||
this.$buefy.toast.open({
|
this.$buefy.toast.open({
|
||||||
message: `'${resp.data.name}' ${typMsg}`,
|
message: `'${d.name}' ${typMsg}`,
|
||||||
type: 'is-success',
|
type: 'is-success',
|
||||||
queue: false,
|
queue: false,
|
||||||
});
|
});
|
||||||
|
@ -344,10 +339,10 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get templates list.
|
// Get templates list.
|
||||||
this.$api.getTemplates().then((r) => {
|
this.$api.getTemplates().then((data) => {
|
||||||
if (r.data.length > 0) {
|
if (data.length > 0) {
|
||||||
if (!this.form.templateId) {
|
if (!this.form.templateId) {
|
||||||
this.form.templateId = r.data.find((i) => i.isDefault === true).id;
|
this.form.templateId = data.find((i) => i.isDefault === true).id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -293,9 +293,9 @@ export default Vue.extend({
|
||||||
|
|
||||||
// Poll for the status as long as the import is running.
|
// Poll for the status as long as the import is running.
|
||||||
this.pollID = setInterval(() => {
|
this.pollID = setInterval(() => {
|
||||||
this.$api.getCampaignStats().then((r) => {
|
this.$api.getCampaignStats().then((data) => {
|
||||||
// Stop polling. No running campaigns.
|
// Stop polling. No running campaigns.
|
||||||
if (r.data.length === 0) {
|
if (data.length === 0) {
|
||||||
clearInterval(this.pollID);
|
clearInterval(this.pollID);
|
||||||
|
|
||||||
// There were running campaigns and stats earlier. Clear them
|
// There were running campaigns and stats earlier. Clear them
|
||||||
|
@ -307,7 +307,7 @@ export default Vue.extend({
|
||||||
} else {
|
} else {
|
||||||
// Turn the list of campaigns [{id: 1, ...}, {id: 2, ...}] into
|
// Turn the list of campaigns [{id: 1, ...}, {id: 2, ...}] into
|
||||||
// a map indexed by the id: {1: {}, 2: {}}.
|
// a map indexed by the id: {1: {}, 2: {}}.
|
||||||
this.campaignStatsData = r.data.reduce((obj, cur) => ({ ...obj, [cur.id]: cur }), {});
|
this.campaignStatsData = data.reduce((obj, cur) => ({ ...obj, [cur.id]: cur }), {});
|
||||||
}
|
}
|
||||||
}, () => {
|
}, () => {
|
||||||
clearInterval(this.pollID);
|
clearInterval(this.pollID);
|
||||||
|
@ -336,8 +336,8 @@ export default Vue.extend({
|
||||||
template_id: c.templateId,
|
template_id: c.templateId,
|
||||||
body: c.body,
|
body: c.body,
|
||||||
};
|
};
|
||||||
this.$api.createCampaign(data).then((r) => {
|
this.$api.createCampaign(data).then((d) => {
|
||||||
this.$router.push({ name: 'campaign', params: { id: r.data.id } });
|
this.$router.push({ name: 'campaign', params: { id: d.id } });
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -185,31 +185,31 @@ export default Vue.extend({
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
// Pull the counts.
|
// Pull the counts.
|
||||||
this.$api.getDashboardCounts().then((r) => {
|
this.$api.getDashboardCounts().then((data) => {
|
||||||
this.counts = r.data;
|
this.counts = data;
|
||||||
this.isCountsLoading = false;
|
this.isCountsLoading = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Pull the charts.
|
// Pull the charts.
|
||||||
this.$api.getDashboardCharts().then((r) => {
|
this.$api.getDashboardCharts().then((data) => {
|
||||||
this.isChartsLoading = false;
|
this.isChartsLoading = false;
|
||||||
|
|
||||||
// vue-c3 lib requires unique instances of Vue() to communicate.
|
// vue-c3 lib requires unique instances of Vue() to communicate.
|
||||||
if (r.data.campaignViews.length > 0) {
|
if (data.campaignViews.length > 0) {
|
||||||
this.chartViewsInst = this;
|
this.chartViewsInst = this;
|
||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.chartViewsInst.$emit('init',
|
this.chartViewsInst.$emit('init',
|
||||||
this.makeChart('Campaign views', r.data.campaignViews));
|
this.makeChart('Campaign views', data.campaignViews));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r.data.linkClicks.length > 0) {
|
if (data.linkClicks.length > 0) {
|
||||||
this.chartClicksInst = new Vue();
|
this.chartClicksInst = new Vue();
|
||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.chartClicksInst.$emit('init',
|
this.chartClicksInst.$emit('init',
|
||||||
this.makeChart('Link clicks', r.data.linkClicks));
|
this.makeChart('Link clicks', data.linkClicks));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
<p><input type="text" name="name" placeholder="Name (optional)" /></p>
|
<p><input type="text" name="name" placeholder="Name (optional)" /></p>
|
||||||
<template v-for="l in publicLists"><span v-if="l.uuid in selected" :key="l.id" :set="id = l.uuid.substr(0, 5)">
|
<template v-for="l in publicLists"><span v-if="l.uuid in selected" :key="l.id" :set="id = l.uuid.substr(0, 5)">
|
||||||
<p>
|
<p>
|
||||||
<input id="{{ id }}" type="checkbox" name="l" value="{{ uuid }}" />
|
<input id="{{ id }}" type="checkbox" name="l" value="{{ l.uuid }}" />
|
||||||
<label for="{{ id }}">{{ l.name }}</label>
|
<label for="{{ id }}">{{ l.name }}</label>
|
||||||
</p></span></template>
|
</p></span></template>
|
||||||
<p><input type="submit" value="Subscribe" /></p>
|
<p><input type="submit" value="Subscribe" /></p>
|
||||||
|
|
|
@ -216,10 +216,10 @@ export default Vue.extend({
|
||||||
|
|
||||||
// Poll for the status as long as the import is running.
|
// Poll for the status as long as the import is running.
|
||||||
this.pollID = setInterval(() => {
|
this.pollID = setInterval(() => {
|
||||||
this.$api.getImportStatus().then((r) => {
|
this.$api.getImportStatus().then((data) => {
|
||||||
this.isProcessing = false;
|
this.isProcessing = false;
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
this.status = r.data;
|
this.status = data;
|
||||||
this.getLogs();
|
this.getLogs();
|
||||||
|
|
||||||
if (!this.isRunning()) {
|
if (!this.isRunning()) {
|
||||||
|
@ -236,8 +236,8 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
getLogs() {
|
getLogs() {
|
||||||
this.$api.getImportLogs().then((r) => {
|
this.$api.getImportLogs().then((data) => {
|
||||||
this.logs = r.data;
|
this.logs = data;
|
||||||
|
|
||||||
Vue.nextTick(() => {
|
Vue.nextTick(() => {
|
||||||
// vue.$refs doesn't work as the logs textarea is rendered dynamiaclly.
|
// vue.$refs doesn't work as the logs textarea is rendered dynamiaclly.
|
||||||
|
@ -271,7 +271,7 @@ export default Vue.extend({
|
||||||
}));
|
}));
|
||||||
params.set('file', this.form.file);
|
params.set('file', this.form.file);
|
||||||
|
|
||||||
// Make the API request.
|
// Post.
|
||||||
this.$api.importSubscribers(params).then(() => {
|
this.$api.importSubscribers(params).then(() => {
|
||||||
// On file upload, show a confirmation.
|
// On file upload, show a confirmation.
|
||||||
this.$buefy.toast.open({
|
this.$buefy.toast.open({
|
||||||
|
|
|
@ -79,11 +79,11 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
createList() {
|
createList() {
|
||||||
this.$api.createList(this.form).then((resp) => {
|
this.$api.createList(this.form).then((data) => {
|
||||||
this.$emit('finished');
|
this.$emit('finished');
|
||||||
this.$parent.close();
|
this.$parent.close();
|
||||||
this.$buefy.toast.open({
|
this.$buefy.toast.open({
|
||||||
message: `'${resp.data.name}' created`,
|
message: `'${data.name}' created`,
|
||||||
type: 'is-success',
|
type: 'is-success',
|
||||||
queue: false,
|
queue: false,
|
||||||
});
|
});
|
||||||
|
@ -91,11 +91,11 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
updateList() {
|
updateList() {
|
||||||
this.$api.updateList({ id: this.data.id, ...this.form }).then((resp) => {
|
this.$api.updateList({ id: this.data.id, ...this.form }).then((data) => {
|
||||||
this.$emit('finished');
|
this.$emit('finished');
|
||||||
this.$parent.close();
|
this.$parent.close();
|
||||||
this.$buefy.toast.open({
|
this.$buefy.toast.open({
|
||||||
message: `'${resp.data.name}' updated`,
|
message: `'${data.name}' updated`,
|
||||||
type: 'is-success',
|
type: 'is-success',
|
||||||
queue: false,
|
queue: false,
|
||||||
});
|
});
|
||||||
|
|
|
@ -108,11 +108,11 @@ export default Vue.extend({
|
||||||
lists: this.form.lists.map((l) => l.id),
|
lists: this.form.lists.map((l) => l.id),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$api.createSubscriber(data).then((resp) => {
|
this.$api.createSubscriber(data).then((d) => {
|
||||||
this.$emit('finished');
|
this.$emit('finished');
|
||||||
this.$parent.close();
|
this.$parent.close();
|
||||||
this.$buefy.toast.open({
|
this.$buefy.toast.open({
|
||||||
message: `'${resp.data.name}' created`,
|
message: `'${d.name}' created`,
|
||||||
type: 'is-success',
|
type: 'is-success',
|
||||||
queue: false,
|
queue: false,
|
||||||
});
|
});
|
||||||
|
@ -136,11 +136,11 @@ export default Vue.extend({
|
||||||
lists: this.form.lists.map((l) => l.id),
|
lists: this.form.lists.map((l) => l.id),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$api.updateSubscriber(data).then((resp) => {
|
this.$api.updateSubscriber(data).then((d) => {
|
||||||
this.$emit('finished');
|
this.$emit('finished');
|
||||||
this.$parent.close();
|
this.$parent.close();
|
||||||
this.$buefy.toast.open({
|
this.$buefy.toast.open({
|
||||||
message: `'${resp.data.name}' updated`,
|
message: `'${d.name}' updated`,
|
||||||
type: 'is-success',
|
type: 'is-success',
|
||||||
queue: false,
|
queue: false,
|
||||||
});
|
});
|
||||||
|
|
|
@ -385,6 +385,7 @@ export default Vue.extend({
|
||||||
bulkChangeLists(action, lists) {
|
bulkChangeLists(action, lists) {
|
||||||
const data = {
|
const data = {
|
||||||
action,
|
action,
|
||||||
|
query: this.fullQueryExp,
|
||||||
target_list_ids: lists.map((l) => l.id),
|
target_list_ids: lists.map((l) => l.id),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -94,11 +94,11 @@ export default Vue.extend({
|
||||||
body: this.form.body,
|
body: this.form.body,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$api.createTemplate(data).then((resp) => {
|
this.$api.createTemplate(data).then((d) => {
|
||||||
this.$emit('finished');
|
this.$emit('finished');
|
||||||
this.$parent.close();
|
this.$parent.close();
|
||||||
this.$buefy.toast.open({
|
this.$buefy.toast.open({
|
||||||
message: `'${resp.data.name}' created`,
|
message: `'${d.name}' created`,
|
||||||
type: 'is-success',
|
type: 'is-success',
|
||||||
queue: false,
|
queue: false,
|
||||||
});
|
});
|
||||||
|
@ -112,11 +112,11 @@ export default Vue.extend({
|
||||||
body: this.form.body,
|
body: this.form.body,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$api.updateTemplate(data).then((resp) => {
|
this.$api.updateTemplate(data).then((d) => {
|
||||||
this.$emit('finished');
|
this.$emit('finished');
|
||||||
this.$parent.close();
|
this.$parent.close();
|
||||||
this.$buefy.toast.open({
|
this.$buefy.toast.open({
|
||||||
message: `'${resp.data.name}' updated`,
|
message: `'${d.name}' updated`,
|
||||||
type: 'is-success',
|
type: 'is-success',
|
||||||
queue: false,
|
queue: false,
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue