2

I would like to do two separate transformations of a single, large store item and commit the results back to the store as two new, additional store items. i.e.

setEventsData: (state, data) => {...} // main huge master object
// do transformations on it then 
setGridData: (state, transformedEventsData) => {}
setCalendarData: (state, differentTransformedEventsData) => {}

My thinking was that I should do the transformations in App.js and commit those to new store items as above because I think it might be better to get all done at page load and have the transformed data read at mapState versus doing the transformation every mount in the Grid and Calendar components. Is this good reasoning?

I am doing something wrong because the original store item state.eventsData keeps getting mangled somewhere along the way during my transformations on local copies. (see the methods transformCalendarData() and transformGridData() below. I don't know why this.eventsData is getting altered, or if this is the best way to do this.

setEventsData mutation and load action

    mutations: {
      setEventsData: (state, data) => {
        state.eventsData = data;
        localStorage.setItem("eventsData", JSON.stringify(data));
      },
    }
    loadData({ commit }) {
      axios
        .get("/data/eventsData.json")
        .then((response) => {
          commit("setEventsData", response.data);
          commit("setLoading", false);
        })
        .catch((error) => {
          console.log(error);
        });
    },

App.js

<template>
  <div id="app">
    <router-view />
  </div>
</template>
<script>
import state from "./store/index";
import { mapState } from "vuex";

export default {
  name: "App",
  data() {
    return {
      calendarData: [],
      gridData: [],
    };
  },
  computed: mapState(["loading", "eventsData"]),
  beforeCreate() {
    state.commit("initializeStore");
  },
  created: function () {
    this.$store.dispatch("loadData");
    this.gridData = this.eventsData;
    this.calendarData = this.eventsData;
  },
  mounted() {
    this.transformDataForGrid();
    this.transformDataForCalendar();
  },
  methods: {
    transformDataForCalendar() {
      this.calendarData.forEach((event, i) => {
        delete event.artist_supporting;
        delete event.genre;
        delete event.venue;
        delete event.venue_city;
        delete event.venue_state;
        delete event.capacity;
        delete event.announce_date;
        delete event.onsale_date;
        delete event.promoter;
        delete event.business_unit;
        delete event.show_type;
        delete event.confirm_date;
        delete event.cancelled_date;
        delete event.status;

        event.venue_id = `event_${i}`;
        event.id = event.venue_id;
        event.title = event.artist_headliner;
        event.startDate = event.event_date;

        delete event.venue_id;
        delete event.artist_headliner;
        delete event.event_date;

        let date = new Date(event.startDate);
        let day = date.getDate();
        let month = date.getMonth() + 1;
        let year = date.getFullYear();
        if (day < 10) {
          day = "0" + day;
        }
        if (month < 10) {
          month = "0" + month;
        }
        event.startDate = year + "-" + month + "-" + day;
      });
      state.commit("setCalendarData", this.calendarData);
    },
    transformDataForGrid() {
      this.gridData.forEach((event) => {
        let date = new Date(event.event_date);
        let day = date.getDate();
        let month = date.getMonth() + 1;
        let year = date.getFullYear();
        if (day < 10) {
          day = "0" + day;
        }
        if (month < 10) {
          month = "0" + month;
        }
        event.event_date = year + "-" + month + "-" + day;
      });
      state.commit("setGridData", this.gridData);
    },
  },
};
</script>

Kirk Ross
  • 3,907
  • 5
  • 39
  • 67
  • Have you thought about using vuex getters instead? you could store the data once and then have two getters `calendarData` and `gridData` that will autoupdate because of vue reactivity. I think that's a more `vuex` way to do that. https://vuex.vuejs.org/guide/getters.html. Make sure you DON'T modify the original data (I see too many `delete` calls), copy the data if you need to modify it so the original don't change. Vuex caches the result of the getters so they are only recalculate when some dependency changes. – arieljuod Jul 09 '20 at 05:12
  • @arieljuod Thanks. That's part of the problem... I *am* copying the data but the original is still getting altered by the `delete` lines and the rest of that function. – Kirk Ross Jul 09 '20 at 05:52
  • This `this.gridData = this.eventsData;` is not copying the data, it just copies the reference, both variables point to the same object if you do that. Personally I wouldn't delete things, use `.filter`, `.select`, `.map`, etc, and create new objects instead of deleting/modifying the existing ones, it's much safer. – arieljuod Jul 09 '20 at 14:02

1 Answers1

1

This 'I am copying the data but the original is still getting altered by the delete lines and the rest of that function' you cant delete it like this eventhough you copy the data [https://stackoverflow.com/questions/34698905/how-can-i-clone-a-javascript-object-except-for-one-key][1]. You can delete them like this const { focus, editable, index, ...rest } = a; then use rest however you want. In your case it should be like:

const { artist_supporting, genre, venue, venue_city, keep going, ...rest } = event; Then again you can use rest how you want you can return it, put into a variable etc..

Elvaleryn
  • 264
  • 4
  • 10
  • Thank you. That makes total sense. That betrays the gaps in my vanilla JavaScript skills! I'll try that tomorrow. – Kirk Ross Jul 09 '20 at 08:15