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.

\$\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\$
    – BCdotWEB
    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
}
\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.