0

I have a modal component which is just a fancy version of the window.confirm, I made it callable everywhere in my nuxt app via injecting in plugins.

components/confirmModal.vue

<template>
  <transition name="fade">
    <div
      v-if="isShow"
      @click="handleClickOverlay"
      class="confirm-modal-overlay"
      id="swConfirm"
    >
      <transition name="zoom">
        <div v-if="isShow" ref="swConfirmDialog" class="confirm-modal-container">
          <span class="confirm-modal-text-grid">
            <h4 v-if="dialog.title" class="confirm-modal-title">{{ dialog.title }}</h4>
            <p v-if="dialog.message" class="confirm-modal-text">{{ dialog.message }}</p>
          </span>
          <div
            class="confirm-modal-btn-grid"
            :class="{ isMono: !dialog.button.no || !dialog.button.yes }"
          >
            <button
              v-if="dialog.button.no"
              @click.stop="e => handleClickButton(e, false)"
              class="confirm-modal-btn left"
            >
              {{ dialog.button.no }}
            </button>

            <button
              v-if="dialog.button.yes"
              @click.stop="e => handleClickButton(e, true)"
              class="confirm-modal-btn"
            >
              {{ dialog.button.yes }}
            </button>
          </div>
        </div>
      </transition>
    </div>
  </transition>
</template>

<script>
import Vue from 'vue'
import { events } from '../plugins/confirm-modal'

Vue.directive('focus', {
  inserted: function(el) {
    el.focus()
  }
})

const Component = {
  name: 'swConfirmDialog',
  data() {
    return {
      isShow: false,
      dialog: {
        title: '',
        message: '',
        button: {}
      },
      params: {}
    }
  },
  methods: {
    resetState() {
      this.dialog = {
        title: '',
        message: '',
        button: {},
        callback: () => {}
      }
    },
    handleClickButton({ target }, confirm) {
      if (target.id == 'swConfirm') return
      this.isShow = false
      if (this.params.callback) {
        this.params.callback(confirm)
      }
    },
    handleClickOverlay({ target }) {
      if (target.id == 'swConfirm') {
        this.isShow = false
        // callback
        if (this.params.callback) {
          this.params.callback(false)
        }
      }
    },
    open(params) {
      this.resetState()
      this.params = params
      this.isShow = true
      Object.entries(params).forEach(param => {
        if (typeof param[1] == typeof this.dialog[param[0]]) {
          this.dialog[param[0]] = param[1]
        }
      })
    },
    registerEvents() {
      events.$on('open', this.open)
      events.$on('close', () => {
        this.handleClickOverlay({ target: { id: 'swConfirm' } })
      })
    }
  },
  mounted() {
    this.registerEvents()
  }
}
export default Component
</script>

plugins/confirm-modal.js

import SwConfirmModal from "~/components/SwConfirmModal.vue"
import Vue from "vue"

export const events = new Vue({
  name: 'sw-confirm-modal'
})

export default (ctx, inject) => {
    Vue.component('sw-confirm-modal', SwConfirmModal)
    const confirm = params => {
      events.$emit('open', params)
    }
    confirm.close = () => {
      events.$emit('close')
    }
    ctx.$confirm = confirm
    inject("confirm", confirm)
  }

and I am calling it in my components like the following codes, but since I want to perform async functions inside my callback I keep getting the error "Syntax Error: Can not use the keyword 'await' outside an async function"

methods: {
    logout(){
      this.$confirm(
        {
          message: `confirm logout?`,
          button: {
            no: 'Cancel',
            yes: 'OK'
          },
          callback: confirm => {
            if (confirm) {
              let res = await this.$auth.logout()
            }
          }
        }
      )
    }
  }
1
  • 1
    So, make the function async. Commented Aug 25, 2020 at 15:37

1 Answer 1

1

Just change the callback to be asynchronous

callback: async (confirm) => {
  if (confirm) {
    let res = await this.$auth.logout()      
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

I didn't know the solution was so simple... I am new to js async. My first attempt was to make the component functions async and that's where I used most of my time. Thank you for leading me to a much more simple answer.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.