3
\$\begingroup\$

I know that if you are using too many if else statements there is a better way, I hope. Please help me learn, thank you everyone. I tried to think of a better way but just couldnt come up with anything better than this.

data is coming from back end as rows from mysql i.e array of objects

<template>
 <div class="col-xs-12 col-sm-12 col-md-12">
 <div class="q-gutter-y-md" style="max-width: 100vw">
 <q-card flat bordered>
 <q-card-section class="text-dark text-center">
 <div class="text-h6">Revenue</div>
 </q-card-section>
 <q-separator inset/>
 <q-card-section>
 <q-tabs
 v-model="tab"
 dense
 class="text-grey"
 active-color="primary"
 indicator-color="primary"
 align="justify"
 narrow-indicator
 >
 <q-tab name="by_time" label="By Time" />
 <q-tab name="by_sellers" label="By Sellers" />
 <q-tab name="by_category" label="By Category" />
 <q-tab name="by_product" label="By Product" />
 </q-tabs>
 <q-separator />
 <q-tab-panels v-model="tab" animated>
 <q-tab-panel name="by_time">
 <q-select filled :options="barTypeSelectOptions" v-model="barTypeModel" ></q-select>
 <apexchart :series="timeSeries" :options="chartOptions" :type="barTypeModel" height="300"/>
 </q-tab-panel>
 <q-tab-panel name="by_sellers">
 <q-select filled :options="barTypeSelectOptions" v-model="barTypeModel" ></q-select>
 <apexchart :series="timeSeries" :options="chartOptions" :type="barTypeModel" height="300"/>
 </q-tab-panel>
 <q-tab-panel name="by_category">
 <q-select filled :options="barTypeSelectOptions" v-model="barTypeModel" ></q-select>
 <apexchart :series="timeSeries" :options="chartOptions" :type="barTypeModel" height="300"/>
 </q-tab-panel>
 <q-tab-panel name="by_product">
 <q-select filled :options="barTypeSelectOptions" v-model="barTypeModel" ></q-select>
 <apexchart :series="timeSeries" :options="chartOptions" :type="barTypeModel" height="300"/>
 </q-tab-panel>
 </q-tab-panels>
 </q-card-section>
 </q-card>
 </div>
 </div>
</template>
<script>
// import Bar from './Bar'
// import monthToNumber from '../assets/monthtonumber.js'
// get "delivered" rows, within a given time interval, from 'order_items' table
export default {
 components: {
 // Bar
 },
 data () {
 return {
 reducerResult: {},
 chartData: null,
 tabCategory: null,
 amount: null,
 tab: 'by_time',
 barTypeSelectOptions: ['bar', 'line'],
 barTypeModel: 'bar',
 timeSeries: [{
 name: 'Sales',
 data: []
 }],
 chartOptions: {
 colors: ['#88C996'],
 grid: {
 show: true,
 strokeDashArray: 1,
 xaxis: {
 lines: {
 show: true
 }
 }
 },
 title: {
 text: 'Column',
 align: 'left',
 style: {
 color: '#FFF'
 }
 },
 fill: {
 type: 'solid',
 gradient: {
 shade: 'dark',
 type: 'vertical',
 shadeIntensity: 0.9,
 inverseColors: false,
 opacityFrom: 1,
 opacityTo: 0.8,
 stops: [0, 50]
 }
 },
 dataLabels: {
 enabled: true
 },
 stroke: {
 curve: 'smooth',
 width: 1.5
 },
 xaxis: {
 categories: ['Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct'],
 labels: {
 style: {
 colors: '#81C784'
 }
 }
 },
 yaxis: {
 title: {
 text: 'Rupees'
 },
 labels: {
 style: {
 color: '#fff'
 }
 }
 },
 tooltip: {
 y: {
 formatter: function (val) {
 return val + ' Rupees'
 }
 }
 }
 }
 }
 },
 methods: {
 async getChartData () {
 const userId = JSON.parse(localStorage.getItem('user')).id
 this.chartData = await this.$axios.get(`/seller_admin/chart_data_all/${this.tab}?userId=${userId}`)
 return this.chartData
 },
 monthReducer (a, i) {
 const newDate = new Date(i.order_creation_date)
 const month = newDate.toLocaleString('default', { month: 'long' })
 a[month] = (a[month] || 0) + i.price // check if the key already has a value, apparently returns 0
 return a
 },
 sellerReducer (a, i) {
 a[i.seller_name] = (a[i.seller_name] || 0) + i.price
 return a
 },
 productReducer (a, i) {
 a[i.product_name] = (a[i.product_name] || 0) + i.price
 return a
 },
 categoryReducer (a, i) {
 a[i.category_name] = (a[i.category_name] || 0) + i.price
 return a
 },
 updateChart (xaxis, yaxis) {
 this.timeSeries = [{
 data: yaxis
 }]
 this.chartOptions = { ...this.chartOptions,
 ...{ xaxis: {
 categories: xaxis
 } }
 }
 },
 setTab () {
 this.tab = 'by_time'
 }
 },
 watch: {
 tab (newv, oldv) {
 if (newv === 'by_time') {
 this.reducerResult = {}
 this.chartData.reduce(this.monthReducer, this.reducerResult)
 this.tabCategory = []
 this.amount = []
 for (const month in this.reducerResult) {
 this.amount.push(this.reducerResult[month])
 this.tabCategory.push(month)
 }
 this.updateChart(this.tabCategory, this.amount)
 } else if (newv === 'by_sellers') {
 this.reducerResult = {}
 this.chartData.reduce(this.sellerReducer, this.reducerResult)
 this.tabCategory = []
 this.amount = []
 for (const seller in this.reducerResult) {
 this.amount.push(this.reducerResult[seller])
 this.tabCategory.push(seller)
 }
 this.updateChart(this.tabCategory, this.amount)
 } else if (newv === 'by_category') {
 this.reducerResult = {}
 this.chartData.reduce(this.categoryReducer, this.reducerResult)
 this.tabCategory = []
 this.amount = []
 for (const category in this.reducerResult) {
 this.amount.push(this.reducerResult[category])
 this.tabCategory.push(category)
 }
 this.updateChart(this.tabCategory, this.amount)
 } else {
 this.reducerResult = {}
 this.chartData.reduce(this.productReducer, this.reducerResult)
 this.tabCategory = []
 this.amount = []
 for (const product in this.reducerResult) {
 this.amount.push(this.reducerResult[product])
 this.tabCategory.push(product)
 }
 this.updateChart(this.tabCategory, this.amount)
 }
 // updatechart garne
 }
 },
 async created () {
 await this.getChartData()
 this.chartData.reduce(this.monthReducer, this.reducerResult)
 this.tabCategory = []
 this.amount = []
 for (const month in this.reducerResult) {
 this.amount.push(this.reducerResult[month])
 this.tabCategory.push(month)
 }
 this.updateChart(this.tabCategory, this.amount)
 }
}
</script>

I also know that if data were formatted properly from backend it would look better in the front. However this is more of a general question as I always end up writing this kind of code.

asked Feb 24, 2020 at 3:35
\$\endgroup\$
1
  • 1
    \$\begingroup\$ The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles. \$\endgroup\$ Commented Feb 24, 2020 at 16:05

1 Answer 1

2
\$\begingroup\$

The only difference in your if/elses looks to be the function you pass to this.chartData.reduce. Everything else is the same, so you can create an object of functions indexed by the newv, and look up the appropriate one to pass.

You can also construct an array of values and an array of keys immediately by using Object.keys and Object.values:

tab (newv, oldv) {
 // you could also define this object elsewhere if you wanted
 const reducersByNewv = {
 by_time: this.monthReducer,
 by_sellers: this.sellerReducers,
 by_category: this.categoryReducer,
 by_product: this.productReducer
 };
 this.reducerResult = this.chartData.reduce(reducersByNewv[newv], {});
 this.tabCategory = Object.keys(this.reducerResult);
 this.amount = Object.values(this.reducerResult);
 this.updateChart(this.tabCategory, this.amount);
 // updatechart garne
}

It also looks like you aren't actually using the reducerResult, tabCategory, or amount anywhere else. If that's true, standalone, function-scoped variables would be more appropriate than assigning to the instance:

tab (newv, oldv) {
 const reducersByNewv = {
 by_time: this.monthReducer,
 by_sellers: this.sellerReducers,
 by_category: this.categoryReducer,
 by_product: this.productReducer
 };
 const reducerResult = this.chartData.reduce(reducersByNewv[newv], {});
 const tabCategory = Object.keys(reducerResult);
 const amount = Object.values(reducerResult);
 this.updateChart(tabCategory, amount);
 // updatechart garne
}
answered Feb 24, 2020 at 3:44
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.