0

I'm looking to format a date fetched via Apollo-GraphQL using the javascript Moment library. I'm using VueJS Apollo on the client side to make graphQL queries as such:

import { ALL_EVENTS } from '../constants/graphql.js'
import Event from './Event'
import moment from 'moment'

export default {
  name: 'EventList',
  data: () => ({
      events: [],
      loading: 0
    }),
  apollo: {
    events: ALL_EVENTS
  },
  components: {
    Event
  },

The apollo middleware returns a list of objects that contain an id, name, a startDate (UTC formatted string) , and an endDate (also a UTC formatted string) property, among other properties added by apollo for it's use.

Whenever I try to make a computed property in VueJS using the object list from Apollo, it gives me a read-only error, but it seems to me like I'm creating a new object:

  computed: {
    eventsFormatted: function () {
      var out = this.events
      for (var i in out) {
        out[i].startDate = moment(out[i].startDate)
        out[i].endDate = moment(out[i].endDate)
      }
      return out
    }
  }

What do I need to do to make a duplicate of the array that I can modify?

Jared
  • 143
  • 1
  • 10

1 Answers1

0

When you do var out = this.events the out var is now pointing to the same array of objects as this.events.

So if this.events is read-only, you'll need to make a copy of the array and if each object in the array is read-only you'll need to make a copy of each object as well.

Here's an example using the spread operator to copy the array and objects:

computed: {
  eventsFormatted() {
    let out = [...this.events];
    for (let i in out) {
      let item = {...out[i]};
      item.startDate = moment(item.startDate);
      item.endDate = moment(item.endDate);
      out[i] = item;
    }
    return out;
  }
}

The above makes a shallow copy of each object in the array. If you need to make a deep copy because of the structure of this.events, see this post.

thanksd
  • 54,176
  • 22
  • 157
  • 150