I am trying to implement a simple authentication in vuejs. I have a list of objects in which I have authentic username and password. I am iterating over this list and checking with the entered username and password. If there is a match then I am emitting an event and updating my variable authenticated. But the problem is inside the login in the forEarch loop i am not able to access the emit.
This is my Login.vue file
<template>
<div id="login">
<h1>Login</h1>
<b-form-input v-model="input.username" placeholder="Username"></b-form-input>
<br/>
<b-form-input v-model="input.password" placeholder="Password" type="password"></b-form-input>
<br/>
<b-button variant="primary" v-on:click="login()">Submit</b-button>
</div>
</template>
<script>
export default {
name: 'Login',
data() {
return {
input: {
username: "",
password: ""
}
}
},
methods: {
login() {
var enteredUsername = this.input.username;
var enteredPassword = this.input.password;
if(enteredUsername !== "" && enteredPassword !== "") {
this.$parent.mockAccount.forEach(function (element) {
if (enteredUsername === element.username && enteredPassword === element.password) {
this.$emit("authenticated", true)
this.$router.replace({name: "secure"})
}
})
}
}
}
}
</script>
<style scoped>
#login {
width: 500px;
border: 1px solid #CCCCCC;
background-color: #FFFFFF;
margin: auto;
margin-top: 200px;
padding: 20px;
}
</style>
I am trying to implement a simple authentication in vuejs. I have a list of objects in which I have authentic username and password. I am iterating over this list and checking with the entered username and password. If there is a match then I am emitting an event and updating my variable authenticated. But the problem is inside the login in the forEarch loop i am not able to access the emit.
This is my Login.vue file
<template>
<div id="login">
<h1>Login</h1>
<b-form-input v-model="input.username" placeholder="Username"></b-form-input>
<br/>
<b-form-input v-model="input.password" placeholder="Password" type="password"></b-form-input>
<br/>
<b-button variant="primary" v-on:click="login()">Submit</b-button>
</div>
</template>
<script>
export default {
name: 'Login',
data() {
return {
input: {
username: "",
password: ""
}
}
},
methods: {
login() {
var enteredUsername = this.input.username;
var enteredPassword = this.input.password;
if(enteredUsername !== "" && enteredPassword !== "") {
this.$parent.mockAccount.forEach(function (element) {
if (enteredUsername === element.username && enteredPassword === element.password) {
this.$emit("authenticated", true)
this.$router.replace({name: "secure"})
}
})
}
}
}
}
</script>
<style scoped>
#login {
width: 500px;
border: 1px solid #CCCCCC;
background-color: #FFFFFF;
margin: auto;
margin-top: 200px;
padding: 20px;
}
</style>
Here is my App.vue file
<template>
<div id="app">
<div id="nav">
<router-link v-if="authenticated" to="/login" v-on:click.native="logout()" replace>Logout</router-link>
</div>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
authenticated: false,
mockAccount: [
{
username: "a",
password: "a"
},
{
username: "rick",
password: "rick2018"
},
{
username: "nick",
password: "nick2018"
},
{
username: "paul",
password: "paul2018"
}]
}
},
mounted() {
if(!this.authenticated) {
this.$router.replace({ name: "Login" });
}
},
methods: {
setAuthenticated(status) {
this.authenticated = status;
},
logout() {
this.authenticated = false;
}
}
}
</script>
<style>
body {
background-color: #F0F0F0;
}
h1 {
padding: 0;
margin-top: 0;
}
#app {
width: 1024px;
margin: auto;
}
</style>
This is the error i am getting
Share Improve this question edited Oct 21, 2019 at 8:34 Chalist 3,3095 gold badges43 silver badges72 bronze badges asked Apr 9, 2019 at 19:29 Siddharth SinhaSiddharth Sinha 6283 gold badges16 silver badges38 bronze badges 1- It is working fine. Thanks a lot for the help!! – Siddharth Sinha Commented Apr 10, 2019 at 15:39
1 Answer
Reset to default 13ES5 functions have their own this
, so change
this.$parent.mockAccount.forEach(function (element) {
if (enteredUsername === element.username && enteredPassword === element.password) {
this.$emit("authenticated", true)
this.$router.replace({name: "secure"})
}
})
either to an ES6 arrow function (which have the same this
as the context they're defined in)
this.$parent.mockAccount.forEach((element) => {
if (enteredUsername === element.username && enteredPassword === element.password) {
this.$emit("authenticated", true)
this.$router.replace({name: "secure"})
}
})
or use explicit binding with Function.prototype.bind()
(ES5):
this.$parent.mockAccount.forEach(function (element) {
if (enteredUsername === element.username && enteredPassword === element.password) {
this.$emit("authenticated", true)
this.$router.replace({name: "secure"})
}
}.bind(this))
or use a closure:
const self = this;
this.$parent.mockAccount.forEach(function (element) {
if (enteredUsername === element.username && enteredPassword === element.password) {
self.$emit("authenticated", true)
self.$router.replace({name: "secure"})
}
})