OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

TypeError: this.$refs is not a function

  • Thread starter Thread starter Joshua
  • Start date Start date
J

Joshua

Guest
So I have a problem with VueJs. I created a "Confirmation Dialogue" and added it to a On-Click-Event on buttons. It worked fine.

Now I tried to copy the implementation to add it to another button on a different parent. It says "TypeError: this.$refs.confirmDialogue.show is not a function" in the Console whenever I try to click the button. The other button still works completly normal.

Am I missing something? I already tried to remove the working button, so only one component uses the Confirm Dialogue but that also didn't work.

I'm new to VueJs. Hope someone can help me with this problem.

Child PopupModal:

Code:
<template>
    <transition name="fade">
        <div class="popup-modal" v-if="isVisible">
            <div class="window">
                <slot></slot>
            </div>
        </div>
    </transition>
</template>

<script>
export default {
    name: 'PopupModal',

    data: () => ({
        isVisible: false,
    }),

    methods: {
        open() {
            this.isVisible = true
        },

        close() {
            this.isVisible = false
        },
    },
}
</script>

<style scoped>
/* css class for the transition */
.fade-enter-active,
.fade-leave-active {
    transition: opacity 0.3s;
}
.fade-enter,
.fade-leave-to {
    opacity: 0;
}

.popup-modal {
    background-color: rgba(0, 0, 0, 0.5);
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 0.5rem;
    display: flex;
    align-items: center;
    z-index: 1;
}

.window {
    background: #fff;
    border-radius: 5px;
    box-shadow: 2px 4px 8px rgba(0, 0, 0, 0.2);
    max-width: 480px;
    margin-left: auto;
    margin-right: auto;
    padding: 1rem;
}
</style>

Parent ConfirmDialogue:

Code:
<template>
    <popup-modal ref="popup">
        <h2 style="margin-top: 0">{{ title }}</h2>
        <p>{{ message }}</p>
        <div class="btns">
            <button class="cancel-btn" @click="_cancel">{{ cancelButton }}</button>
            <span class="ok-btn" @click="_confirm">{{ okButton }}</span>
        </div>
    </popup-modal>
</template>

<script>
import PopupModal from "../confirmDialogue/PopupModal.vue"

export default {
    name: 'ConfirmDialogue',

    components: { PopupModal },

    data: () => ({
        // Parameters that change depending on the type of dialogue
        title: undefined,
        message: undefined, // Main text content
        okButton: undefined, // Text for confirm button; leave it empty because we don't know what we're using it for
        cancelButton: 'Abbrechen', // text for cancel button
        
        // Private variables
        resolvePromise: undefined,
        rejectPromise: undefined,
    }),

    methods: {
        show(opts = {}) {
            this.title = opts.title
            this.message = opts.message
            this.okButton = opts.okButton
            if (opts.cancelButton) {
                this.cancelButton = opts.cancelButton
            }
            // Once we set our config, we tell the popup modal to open
            this.$refs.popup.open()
            // Return promise so the caller can get results
            return new Promise((resolve, reject) => {
                this.resolvePromise = resolve
                this.rejectPromise = reject
            })
        },

        _confirm() {
            this.$refs.popup.close()
            this.resolvePromise(true)
        },

        _cancel() {
            this.$refs.popup.close()
            this.resolvePromise(false)
            // Or you can throw an error
            // this.rejectPromise(new Error('User cancelled the dialogue'))
        },
    },
}
</script>

<style scoped>
.btns {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
}

.ok-btn {
    padding: 0.5em 1em;
    background-color: #1F51FF;
    color: #fff;
    border: 2px solid #0ec5a4;
    border-radius: 5px;
    font-size: 16px;
    text-transform: uppercase;
    cursor: pointer;
}

.cancel-btn {
    padding: 0.5em 1em;
    background-color: #d5eae7;
    color: #000;
    border: 2px solid #0ec5a4;
    border-radius: 5px;
    font-size: 16px;
    text-transform: uppercase;
    cursor: pointer;
}
</style>

Working button:

Code:
            <td class="last-td last-row">
                <div class="button-wrapper">
                    <div class="wrapper-edit">
                        <button class="button button-edit">Bearbeiten</button>
                    </div>
                    <div class="wrapper-cancel">
                        <button class="button button-cancel" @click="doDelete">Löschen</button> <!-- Here is the working button -->
                        <confirm-dialogue ref="confirmDialogue"></confirm-dialogue>
                    </div>
                </div>
            </td>
        </tr>
    </thead>
</template>

<script>
import ConfirmDialogue from '../confirmDialogue/ConfirmDialogue.vue'

export default {
    name: "bookingElements",

    components: { ConfirmDialogue },
    
    methods: {
        async doDelete() {
            const ok = await this.$refs.confirmDialogue.show({
                title: 'Buchung löschen',
                message: 'Sind Sie sicher, dass Sie die Buchung löschen wollen?',
                okButton: 'Buchung löschen',
            })
            if (ok) {
                alert('Die Buchung wurde Erfolgreich gelöscht')
            }
        },

Button that isn't working:

Code:
            <td id="buttonCell">
                <button class="button" @click="doDelete">Buchen</button>
                <confirm-dialogue ref="confirmDialogue"></confirm-dialogue>
            </td>
        </tr>
    </tbody>
</template>

<script>
import ConfirmDialogue from "../confirmDialogue/ConfirmDialogue.vue"

export default {
    name: "bookElements",

    components: { ConfirmDialogue },

    methods: {
        async doDelete() {
            const ok = await this.$refs.confirmDialogue.show({
                title: 'Buchung löschen',
                message: 'Sind Sie sicher, dass Sie die Buchung löschen wollen?',
                okButton: 'Buchung löschen',
            })
            if (ok) {
                alert('Die Buchung wurde Erfolgreich gelöscht')
            }
        },
<p>So I have a problem with VueJs. I created a "Confirmation Dialogue" and added it to a On-Click-Event on buttons. It worked fine.</p>
<p>Now I tried to copy the implementation to add it to another button on a different parent. It says <strong>"TypeError: this.$refs.confirmDialogue.show is not a function"</strong> in the Console whenever I try to click the button. The other button still works completly normal.</p>
<p>Am I missing something? I already tried to remove the working button, so only one component uses the Confirm Dialogue but that also didn't work.</p>
<p>I'm new to VueJs. Hope someone can help me with this problem.</p>
<p>Child PopupModal:</p>
<pre><code><template>
<transition name="fade">
<div class="popup-modal" v-if="isVisible">
<div class="window">
<slot></slot>
</div>
</div>
</transition>
</template>

<script>
export default {
name: 'PopupModal',

data: () => ({
isVisible: false,
}),

methods: {
open() {
this.isVisible = true
},

close() {
this.isVisible = false
},
},
}
</script>

<style scoped>
/* css class for the transition */
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}

.popup-modal {
background-color: rgba(0, 0, 0, 0.5);
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
padding: 0.5rem;
display: flex;
align-items: center;
z-index: 1;
}

.window {
background: #fff;
border-radius: 5px;
box-shadow: 2px 4px 8px rgba(0, 0, 0, 0.2);
max-width: 480px;
margin-left: auto;
margin-right: auto;
padding: 1rem;
}
</style>
</code></pre>
<p>Parent ConfirmDialogue:</p>
<pre><code><template>
<popup-modal ref="popup">
<h2 style="margin-top: 0">{{ title }}</h2>
<p>{{ message }}</p>
<div class="btns">
<button class="cancel-btn" @click="_cancel">{{ cancelButton }}</button>
<span class="ok-btn" @click="_confirm">{{ okButton }}</span>
</div>
</popup-modal>
</template>

<script>
import PopupModal from "../confirmDialogue/PopupModal.vue"

export default {
name: 'ConfirmDialogue',

components: { PopupModal },

data: () => ({
// Parameters that change depending on the type of dialogue
title: undefined,
message: undefined, // Main text content
okButton: undefined, // Text for confirm button; leave it empty because we don't know what we're using it for
cancelButton: 'Abbrechen', // text for cancel button

// Private variables
resolvePromise: undefined,
rejectPromise: undefined,
}),

methods: {
show(opts = {}) {
this.title = opts.title
this.message = opts.message
this.okButton = opts.okButton
if (opts.cancelButton) {
this.cancelButton = opts.cancelButton
}
// Once we set our config, we tell the popup modal to open
this.$refs.popup.open()
// Return promise so the caller can get results
return new Promise((resolve, reject) => {
this.resolvePromise = resolve
this.rejectPromise = reject
})
},

_confirm() {
this.$refs.popup.close()
this.resolvePromise(true)
},

_cancel() {
this.$refs.popup.close()
this.resolvePromise(false)
// Or you can throw an error
// this.rejectPromise(new Error('User cancelled the dialogue'))
},
},
}
</script>

<style scoped>
.btns {
display: flex;
flex-direction: row;
justify-content: space-between;
}

.ok-btn {
padding: 0.5em 1em;
background-color: #1F51FF;
color: #fff;
border: 2px solid #0ec5a4;
border-radius: 5px;
font-size: 16px;
text-transform: uppercase;
cursor: pointer;
}

.cancel-btn {
padding: 0.5em 1em;
background-color: #d5eae7;
color: #000;
border: 2px solid #0ec5a4;
border-radius: 5px;
font-size: 16px;
text-transform: uppercase;
cursor: pointer;
}
</style>
</code></pre>
<p>Working button:</p>
<pre><code> <td class="last-td last-row">
<div class="button-wrapper">
<div class="wrapper-edit">
<button class="button button-edit">Bearbeiten</button>
</div>
<div class="wrapper-cancel">
<button class="button button-cancel" @click="doDelete">Löschen</button> <!-- Here is the working button -->
<confirm-dialogue ref="confirmDialogue"></confirm-dialogue>
</div>
</div>
</td>
</tr>
</thead>
</template>

<script>
import ConfirmDialogue from '../confirmDialogue/ConfirmDialogue.vue'

export default {
name: "bookingElements",

components: { ConfirmDialogue },

methods: {
async doDelete() {
const ok = await this.$refs.confirmDialogue.show({
title: 'Buchung löschen',
message: 'Sind Sie sicher, dass Sie die Buchung löschen wollen?',
okButton: 'Buchung löschen',
})
if (ok) {
alert('Die Buchung wurde Erfolgreich gelöscht')
}
},
</code></pre>
<p>Button that isn't working:</p>
<pre><code> <td id="buttonCell">
<button class="button" @click="doDelete">Buchen</button>
<confirm-dialogue ref="confirmDialogue"></confirm-dialogue>
</td>
</tr>
</tbody>
</template>

<script>
import ConfirmDialogue from "../confirmDialogue/ConfirmDialogue.vue"

export default {
name: "bookElements",

components: { ConfirmDialogue },

methods: {
async doDelete() {
const ok = await this.$refs.confirmDialogue.show({
title: 'Buchung löschen',
message: 'Sind Sie sicher, dass Sie die Buchung löschen wollen?',
okButton: 'Buchung löschen',
})
if (ok) {
alert('Die Buchung wurde Erfolgreich gelöscht')
}
},
</code></pre>
Continue reading...
 

Online statistics

Members online
0
Guests online
4
Total visitors
4
Top