Iterating through a list to generate calendars I'm iterating through a list to generate calendars, the issue is each generator function has the same this.addToCalendar() function. I'd like to know how I could condense this into only being called once, rather than in each function.
The main generators I'd like to look at are the ones within method, where I am generating calendar links as well as calling an external api.
CSS has been removed to focus on JS logic.
&lt;template&gt;
&lt;div&gt;
  &lt;ul&gt;
    &lt;li v-for=&quot;(calendar, i) in calendars&quot; :key=&quot;i&quot;&gt;
      &lt;button @click=&quot;calendar.generator&quot;&gt;
        &lt;span&gt;{{ calendar.type }}&lt;/span&gt;
      &lt;/button&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;button @click=&quot;setExpanded(false)&quot;&gt;
    Close
  &lt;/button&gt;
&lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
import {
  ICalendar,
  GoogleCalendar,
  OutlookCalendar,
  YahooCalendar,
} from 'datebook'
import { mapActions, mapGetters } from 'vuex'

export default {
  data() {
    return {
      calendars: [
        { type: 'Apple', generator: this.generateAppleCalendar },
        { type: 'Google', generator: this.generateGoogleCalendar },
        { type: 'Outlook', generator: this.generateOutlookCalendar },
        { type: 'Yahoo', generator: this.generateYahooCalendar },
      ],
      success: null,
      error: null,
    }
  },
  computed: {
    ...mapGetters({
      event: 'event/event',
      expanded: 'calendar/expanded',
      userType: 'user/userType',
    }),
    eventLocation() {
      return `${this.event.location_street}, ${this.event.location_city}, ${this.event.location_state}. ${this.event.location_zip}`
    },
    generateConfig() {
      const config = {
        title: this.event.title,
        location: this.eventLocation,
        description: this.event.description,
        start: new Date(this.event.start_time),
        end: new Date(this.event.end_time),
      }
      return config
    },
  },
  methods: {
    ...mapActions({
      setExpanded: 'calendar/setExpanded',
    }),
    generateAppleCalendar() {
      const icalendar = new ICalendar(this.generateConfig)
      icalendar.download()
      this.addToCalendar()
    },
    generateGoogleCalendar() {
      const googleCalendar = new GoogleCalendar(this.generateConfig)
      this.openInNewTab(googleCalendar.render())
      this.addToCalendar()
    },

    generateOutlookCalendar() {
      const outlookCalendar = new OutlookCalendar(this.generateConfig)
      this.openInNewTab(outlookCalendar.render())
      this.addToCalendar()
    },
    generateYahooCalendar() {
      const yahooCalendar = new YahooCalendar(this.generateConfig)
      this.openInNewTab(yahooCalendar.render())
      this.addToCalendar()
    },
    openInNewTab(url) {
      const win = window.open(url, '_blank') // Opening a new tab with the url
      win.focus() // Focussing the users browser to new tab
    },
    async addToCalendar() {
      let url

      if (this.userType === 'guest') {
        url = `event/${this.event.id}/add-guest-user`
      } else {
        url = `event/${this.event.id}/guest`
      }

      const response = await this.$axios.post(url)
      if (response.status === 201) {
        this.success = true
      } else {
        this.error = true
      }
    },
  },
}
&lt;/script&gt;
I'd like to know how I could condense this into only being called once, rather than in each function.

One option would be to make a method that accepted the calendar or type and called the associated method
methods:
    generateCalendar(type) {
        const generateMethod = `generate${type}Calendar`
        if (typeof this[generateMethod] === 'function')
          this[generateMethod]()
          this.addToCalendar()
        }
      }

Then pass the type:
&lt;button @click=&quot;generateCalendar(calendar.type)&quot;&gt;

If the only property being accessed in the loop was that type property then destructuring assignment would allow it to be simplified:
 &lt;li v-for=&quot;({ type }, i) in calendars&quot; :key=&quot;i&quot;&gt;
   &lt;button @click=&quot;generateCalendar(type)&quot;&gt; 
      &lt;span&gt;{{ calendar.type }}&lt;/span&gt;
    &lt;/button
     

Alternatively, with using the method above the generator properties of the calendars could be removed, and calendars could perhaps just be an array of strings.
Also, it seems that three of the four calendar methods are nearly identical other than the class of calendar object created: generateGoogleCalendar, generateOutlookCalendar and generateYahooCalendar. A generic method could be used to replace those three methods (and accept the calendar type as a parameter to be used to dynamically invoke a constructor) or create them dynamically in a loop.