javascriptvue.jschartsvisual-web-developer

How can I update the contents of initialized array after executing the fetchData method?


I'm relatively new to Vue.js, and I'm working on a project where I need to update initialized arrays within the data() section of my component using the fetchData method. Here's a simplified version of my code:

<script>
  import axios from 'axios';
  import Footer from '@/components/Footer'; 
  import Sidebar from '@/components/Sidebar'; 
  import BarChart from '@/components/ChartJS/Barchart';
 

  
  export default {
    name: 'Dashboard',
    components: {
      Footer,
      Sidebar, 
      BarChart,
     
  
    },
    data() {

  const data1 = [];
  const data2 = [];
  const data3 = [];
  const data4 = [];
  const data5 = [];
  const data6 = [];

//I want to make the data being processed in the fetchData method to be updated right here

  const data1Count = data1.length;
  const data2Count  = data2.length;
  const data3Count  = data3.length;
  const data4Count = data4.length;
  const data5Count = data5.length;
  const data6Count = data6.length;
      return {

    Cluster: {
        labels: ['Data 1', 
                  'Data 2', 
                  'Data 3',  
                  'Data 4',
                  'Data 5', 
                  'Data 6',
                 ],
         values: [data1Count , data2Count  , data3Count  , data4Count , data5Count , data6Count ],
         backgroundColor: ['rgba(25, 82, 105, 0.6'],
          },
      };
    },

    methods: {
    fetchData() {
      axios
        .get('http://127.0.0.1:8000/api/dataList')
        .then(response => {

          this.data1 = [];
          this.data2  = [];
          this.data3  = [];
          this.data4 = [];
          this.data5  = [];
          this.data6 = [];

          response.data.forEach(item => {
            const clusterName = item.Cluster;

            switch (clusterName) {
              case 'Data 1':
                this.data1.push(item);
                break;
              case 'Data 2':
                this.data2.push(item);
                break;
              case 'Data 3':
                this.data3.push(item);
                break;
              case 'Data 4':
                this.data4.push(item);
                break;

              case 'Data 5':
                this.data5.push(item);
                break;  
                
              case 'Data 6':
                this.data6.push(item);
                break; 

              default:
                break;
            }
          }
          );
          
        })
        .catch(error => {
          console.error('Error fetching data:', error);
        });
    },
  },
  mounted() {
    this.fetchData();
  },
  };
  </script>

My challenge is getting the fetchData method to directly update the initialized arrays (data1, data2, data3, data4, data5, and data6) within the data() section. I want to dynamically populate these arrays with data retrieved from an API through the fetchData method. The goal is to make these arrays readily available for use in my charting component.

Any guidance, examples, or best practices on how to achieve this would be greatly appreciated. I'm relatively new to Vue.js, and a step-by-step explanation or code snippets would be particularly helpful. Thank you in advance for your assistance!


Solution

  • So if I understand this properly, you want to get items array from your api. Then append those items to the relevant arrays and then add the length of those array to Cluster.values property.

    You do not need to have that many arrays in your data() section of the code. I suggest using an Object/Map to store it. You can do that in the following way (namesMap):

    data() { 
      return {
        namesMap: {'Data 1': [], 'Data 2': [], 'Data 3': [], ...},
        Cluster: {
            labels: ['Data 1', 'Data 2', 'Data 6'],
            values: [],
            backgroundColor: ['rgba(25, 82, 105, 0.6']
        },
      };
    

    }

    After that in your methods section you can make the api call, loop all the items and check if their names match the one you have in your namesMap. Only then do you add that item to the corresponding list.

    methods: {
    async fetchData () {
        const items = await axios.get('.../api/dataList')
        for (let i = 0; i < items.length; i++) {
            const clusterName = items[i].Cluster
            if (clusterName in Object.keys(this.namesMap)) {
                this.namesMap[clusterName].push(items[i])
            }
        }
        // fill the Cluster.values prop
        Object.keys(this.namesMap).forEach(k => {
            this.Cluster.values.push(this.namesMap[k].length)
        })
        // also do not forget to reset the values of namesMap at the end so that the next loop can work properly
        this.namesMap = {'Data 1': [], 'Data 2': []}
    },