How to call components with function/method in pages? - vue.js

My partner create a login page with several components like "email", "password", "phone number", "login button" and "forgot password". But then ask me to move all the components into new vue under '/components' folder. I only know to move the components but I cannot make it functional since the method is not callable. Please help.
original login page:
<template>
<div class="q-pa-md" style="width: 400px">
<q-form
#submit="onSubmit"
#reset="onReset"
class="q-gutter-md"
>
<!-- <q-input
filled
v-model="email"
label="Your email *"
lazy-rules
:rules="[val => !!val || 'Email is missing', isValidEmail]"
/>
<q-input
filled
type="password"
v-model="password"
label="Password *"
hint="Password should be 8 characters"
lazy-rules
:rules="[
val => val !== null && val !== '' || 'Please enter your password',
val => val.length === 8 || 'Please enter a valid password'
]"
/>
<q-input
filled
type="number"
v-model="phone"
label="Your phone number *"
lazy-rules
:rules="[
val => val !== null && val !== '' || 'Please enter your phone number',
val => val.length > 8 && val.length < 12 || 'Please enter a valid number'
]"
/>
<div>
<q-btn label="Login" type="submit" color="primary"/>
<q-btn flat to="/user/requestpassword" label="Forgot Password?" type="submit"/>
</div> -->
</q-form>
</div>
</template>
<script>
export default {
data () {
return {
email: null,
password: null,
phone: null,
accept: false
}
},
methods: {
isValidEmail (val) {
const emailPattern = /^(?=[a-zA-Z0-9#._%+-]{6,254}$)[a-zA-Z0-9._%+-]{1,64}#(?:[a-zA-Z0-9-]{1,63}\.){1,8}[a-zA-Z]{2,63}$/
return emailPattern.test(val) || 'Invalid email'
},
onSubmit () {
if (this.accept !== true) {
this.$q.notify({
color: 'red-5',
textColor: 'white',
icon: 'warning'
})
} else {
this.$q.notify({
color: 'green-4',
textColor: 'white',
icon: 'cloud_done',
message: 'Submitted'
})
}
this.onReset()
},
onReset () {
this.email = null
this.password = null
this.phone = null
this.accept = false
}
}
}
</script>
new component vue:
<template>
<q-input
filled
v-model="email"
label="Your email *"
lazy-rules
:rules="[val => !!val || 'Email is missing', isValidEmail]"
/>
<q-input
filled
type="password"
v-model="password"
label="Password *"
hint="Password should be 8 characters"
lazy-rules
:rules="[
val => val !== null && val !== '' || 'Please enter your password',
val => val.length === 8 || 'Please enter a valid password'
]"
/>
<q-input
filled
type="number"
v-model="phone"
label="Your phone number *"
lazy-rules
:rules="[
val => val !== null && val !== '' || 'Please enter your phone number',
val => val.length > 8 && val.length < 12 || 'Please enter a valid number'
]"
/>
<div>
<q-btn label="Login" type="submit" color="primary"/>
<q-btn flat to="/user/requestpassword" label="Forgot Password?" type="submit"/>
</div>
</template>
<script>
export default {
}
</script>

<div id="parent">
<child :delegate="delegateMethod" ref="child" />
</div>
<script>
import { ref } from "vue";
export default({
setup() {
const child = ref()
const callChildMethod = () => {
child.method();
};
const delegateMethod = () => {
console.log("call from child");
};
return { delegateMethod };
}
});
</script>
<div id="child">
<p>child component</p>
<button #click="responseToParent()">
</div>
<script>
export default({
props: {
delegate: {
type: Function,
default: () => {}
}
},
setup(props) {
const method = () => {
console.log("call from parent");
};
const responseToParent = () => {
props.delegate();
};
return { responseToParent };
}
});
</script>
This is a very simple example. It works like this between parent and child components in Vue.

Related

NextJS Mailchimp API Error Handling and useState

thanks a lot for taking a look at my problem.
I've been building a button to handle a Mailchimp API call but I can't seem to be able to piece it all together using useState. I would really appreciate some help with this as it is currently throwing 500 errors when successfully added to the mailing list with new email addresses and the response from Mailchimp seems to be fine.
I know there is probably some sort of react hook or other shortcut I could use but I really want to make this work..! hahaa!
api/subscribe.js
export default function handler(req, res) {
const { email } = req.body;
console.log(`email: ${email}`);
if (!email) {
return res.status(400).json({ error: 'Email is required' });
}
try {
const client = require('#mailchimp/mailchimp_marketing');
const API_KEY = process.env.MAILCHIMP_API_KEY;
const API_SERVER = process.env.MAILCHIMP_API_SERVER;
const LIST_ID = process.env.MAILCHIMP_AUDIENCE_ID;
client.setConfig({
apiKey: API_KEY,
server: API_SERVER,
});
const run = async () => {
const response = await client.lists.addListMember(LIST_ID, {
email_address: `${email}`,
status: 'pending',
skip_merge_validation: true,
});
console.log(response);
};
run();
if (response.status >= 400) {
return res.status(400).json({
error: `There was an error subscribing your email address to the newsletter.
Please contact us directly so we can add you in manually. Sorry for any inconvenience.`,
});
}
return res.status(201).json({
message: 'Success! 🎉 You are now subscribed to the newsletter.',
});
} catch (err) {
console.log(res.error);
return res.status(500).json({ error: '***ERROR***' });
}
}
My messy but functional code..!
components/Contact.js
import React, { useState } from 'react';
import LoadingSpinner from '../components/LoadingSpinner';
import { CountdownCircleTimer } from 'react-countdown-circle-timer';
export default function Contact() {
const [email, setEmail] = useState('');
const [message, setMessage] = useState('');
// const [loading, setLoading] = useState(true);
const [state, setState] = useState('IDLE');
const subscribe = async (e) => {
e.preventDefault();
setState('LOADING');
setMessage(null);
try {
const res = await fetch('/api/subscribe', {
body: JSON.stringify({
email: email,
}),
headers: {
'Content-Type': 'application/json',
},
method: 'POST',
});
console.log(res);
if (res.status >= 400) {
console.log(res.error);
setState('ERROR');
setMessage(
<div>
An error has occurred, please{' '}
<a
href="/contact"
target="_blank"
rel="noreferrer"
className="text-blue-500 underline cursor-pointer transition-transform duration-7000 hover:text-gray-200"
onClick={() => {
setState('IDLE');
setMessage(null);
setEmail('');
}}
>
contact us
</a>
</div>
);
setEmail('');
setTimeout(() => {
setState('IDLE');
setMessage(null);
}, 10000);
return;
}
setState('SUCCESS');
setMessage('Success! 🎉 You are now subscribed to the newsletter.');
setEmail('');
setTimeout(() => {
setState('IDLE');
setMessage(null);
}, 10000);
return;
} catch (e) {
setState('ERROR');
console.log(e.res.error);
setMessage(e.res.error);
setEmail('');
setTimeout(() => {
setState('IDLE');
setMessage(null);
}, 10000);
return;
}
};
return (
<div className="h-[15rem] xs:h-[13.5rem] xsm:h-[12.5rem] sm:h-[13rem] w-full bg-black/90 px-2">
<div className="flex justify-center items-center">
<h1 className="text-center text-zinc-300 text-lg md:text-2xl mt-4">
Sign up to the Newsletter...
</h1>
</div>
<div className="flex justify-center items-center w-full">
<form onSubmit={subscribe}>
<input
type="email"
id="email-input"
name="email"
placeholder="Your#email.here"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
autoCapitalize="off"
autoCorrect="off"
aria-autocomplete="list"
className="h-[40px] min-w-[270px] md:min-w-[400px] border border-black/60 rounded-xl w-full text-center text-md px-2"
/>
<div className="flex justify-center items-center py-2">
{state === 'IDLE' && (
<button
type="submit"
value=""
name="subscribe"
disabled={state === 'LOADING'}
className="w-[200px] h-[40px] px-12 mt-2 text-lg border border-black/60 rounded-xl bg-gray-200 text-gray-900 transition-colors duration-700 transform hover:bg-gray-500 hover:text-gray-100"
>
Subscribe
</button>
)}
{state === 'ERROR' && (
<div className="h-[50px]">
<CountdownCircleTimer
isPlaying
size={55}
strokeWidth={2}
duration={10}
trailColor="#3399ff"
rotation="clockwise"
colors="#ffffff"
>
{({ remainingTime }) => remainingTime}
</CountdownCircleTimer>
</div>
)}
{state === 'SUCCESS' && (
<div className="h-[50px]">
<CountdownCircleTimer
isPlaying
size={50}
duration={10}
colors={[
['#004777', 0.33],
['#F7B801', 0.33],
['#A30000', 0.33],
]}
>
{({ remainingTime }) => remainingTime}
</CountdownCircleTimer>
</div>
)}
{state === 'LOADING' && (
<button
type="submit"
value=""
disabled
name="subscribe"
className="w-[200px] h-[40px] px-12 mt-2 text-lg border border-black/60 rounded-xl bg-gray-200 text-gray-900 transition-colors duration-700 transform"
>
<div className="flex justify-center items-center">
<LoadingSpinner />
</div>
</button>
)}
</div>
<div className="text-zinc-300 text-sm md:text-lg text-center md:min-w-[35ch]">
{message
? message
: `We only send emails when we have genuine news.`}
</div>
</form>
</div>
</div>
);
}
response from Mailchimp (with sensitive info taken out)
email: becir28216#jernang.com
undefined
{
id: '',
email_address: 'becir28216#jernang.com',
unique_email_id: '',
contact_id: '',
full_name: '',
web_id: ,
email_type: 'html',
status: 'pending',
consents_to_one_to_one_messaging: true,
merge_fields: { FNAME: '', LNAME: '' },
stats: { avg_open_rate: 0, avg_click_rate: 0 },
ip_signup: '',
timestamp_signup: '2022-11-15T20:46:33+00:00',
ip_opt: '',
timestamp_opt: '',
member_rating: 2,
last_changed: '2022-11-15T20:46:33+00:00',
language: '',
vip: false,
email_client: '',
location: {
latitude: 0,
longitude: 0,
gmtoff: 0,
dstoff: 0,
country_code: '',
timezone: '',
region: ''
},
source: 'API - Generic',
tags_count: 0,
tags: [],
list_id: '',
...}
I want to change the state of the button according to the response from the API call. I have been trying all sorts of combinations and now my head hurts..
Expected behaviour:
When it is idle, button says Subscribe and the normal message is displayed below it.
when it is loading, the button displays the loading spinner and still displays the normal message
When there is an error, the button displays the countdowntimer and the error message.
When the API call is a success, the loading spinner disappears, the success message is displayed and then 10 seconds later, the whole form resets again.

How to toggle show hide functionality for multiple fields in formik?

import React, { Fragment, useState, useEffect } from "react";
import { useSelector, useDispatch, connect } from "react-redux";
import { useNavigate } from "react-router";
import { Field, Form, Formik } from "formik";
import VisibilityIcon from "#material-ui/icons/Visibility";
import VisibilityOffIcon from "#material-ui/icons/VisibilityOff";
import { changePassword } from "../../Redux/Actions/changePasswordAction";
import { passwordErrors, roles } from "../Shared/constants";
import Alert from "../Modal/modal";
import "./ChangePassword.css";
function ChangePassword() {
const [showPassword1, setShowPassword1] = useState(false);
const [showPassword2, setShowPassword2] = useState(false);
const [showPassword3, setShowPassword3] = useState(false);
const alert = useSelector((state) => state.alert);
enter code here
const role_id = localStorage.getItem("role_id");
//Redux Dispatch:
const dispatch = useDispatch();
//Used to navigate
const navigation = useNavigate();
const passwords = {
currentPassword: "",
newPassword: "",
confirmNewPassword: "",
};
// function toggleShowPassword(clickedField) {
// if (clickedField === showPassword1) {
// setShowPassword1(!showPassword1) &&
// setShowPassword2(showPassword2) &&
// setShowPassword3(showPassword3);
// } else if (clickedField === showPassword2) {
// setShowPassword2(!showPassword2) &&
// setShowPassword1(showPassword1) &&
// setShowPassword3(showPassword3);
// } else {
// setShowPassword3(!showPassword3) &&
// setShowPassword1(showPassword1) &&
// setShowPassword2(showPassword2);
// }
// }
function toggleShowPassword1() {
setShowPassword1(!showPassword1);
}
function toggleShowPassword2() {
setShowPassword2(!showPassword2);
}
function toggleShowPassword3() {
setShowPassword3(!showPassword3);
}
//Alert
useEffect(() => {
if (Number(role_id) === roles.TRAINER_ROLE_ID) {
if (alert.type === "success_clear") {
navigation("/trainer-profile");
}
} else {
if (alert.type === "success_clear") {
navigation("/user-profile");
}
}
}, [alert, navigation, role_id]);
function validate(passwords) {
const errors = {};
if (passwords.currentPassword === "") {
errors.currentPassword = passwordErrors.PASSWORD;
}
if (passwords.newPassword === passwords.currentPassword) {
errors.newPassword = passwordErrors.OLD_NEW_SAME;
}
if (passwords.newPassword === "") {
errors.newPassword = passwordErrors.PASSWORD;
} else if (
!/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!##%&])(?=.{8,})/.test(
passwords.newPassword
)
) {
errors.newPassword = passwordErrors.PASSWORD_INVALID;
}
if (passwords.confirmNewPassword === "") {
errors.confirmNewPassword = passwordErrors.CONFIRM_PASSWORD;
} else if (passwords.confirmNewPassword !== passwords.newPassword) {
errors.confirmNewPassword = passwordErrors.PASSWORDS_UNMATCHED;
}
return errors;
}
function handleChangePassword(passwords) {
const id = localStorage.getItem("user_id");
const passwordsData = {
oldPassword: passwords.currentPassword,
password: passwords.confirmNewPassword,
};
dispatch(changePassword(id, passwordsData));
}
return (
<Fragment>
<div className="row">
<div className="col">
<span className="main-heading mx-4">Change Account Password</span>
<div className="mx-4">
<hr></hr>
</div>
</div>
</div>
{alert.message && <Alert show={true} />}
<div className="passwords">
<Formik
initialValues={passwords}
validate={(values) => validate(values)}
onSubmit={(values) => handleChangePassword(values)}
>
{({ errors, touched }) => (
<Form>
<div className="row">
<div className="col-md">
<div className="form-group mb-4">
<label htmlFor="currentPassword" className="cp-label">
Current Password
</label>
<div className="input-group">
<Field
type={showPassword1 ? "text" : "password"}
id="currentPassword"
name="currentPassword"
placeholder="Enter your Current password"
className={
errors.currentPassword && touched.currentPassword
? "form-control primary-input-field is-invalid pass"
: "form-control primary-input-field pass"
}
/>
<span
className="input-group-text"
id="basic-addon2"
// onClick={() => toggleShowPassword(showPassword1)}
onClick={toggleShowPassword1}
>
{showPassword1 ? (
<VisibilityIcon
fontSize="small"
className="iconColor"
/>
) : (
<VisibilityOffIcon
fontSize="small"
className="iconColor"
/>
)}
</span>
{touched.currentPassword && errors.currentPassword ? (
<div className="invalid-feedback">
{errors.currentPassword}
</div>
) : null}
</div>
</div>
</div>
</div>
<div className="row">
<div className="col-md">
<div className="form-group mb-4">
<label htmlFor="newPassword" className="cp-label">
New Password
</label>
<div className="input-group">
<Field
type={showPassword2 ? "text" : "password"}
id="newPassword"
name="newPassword"
placeholder="Enter your New password"
className={
errors.newPassword && touched.newPassword
? "form-control primary-input-field is-invalid pass"
: "form-control primary-input-field pass"
}
/>
<span
className="input-group-text"
id="basic-addon2"
// onClick={() => toggleShowPassword(showPassword2)}
onClick={toggleShowPassword2}
>
{showPassword2 ? (
<VisibilityIcon
fontSize="small"
className="iconColor"
/>
) : (
<VisibilityOffIcon
fontSize="small"
className="iconColor"
/>
)}
</span>
{touched.newPassword && errors.newPassword ? (
<div className="invalid-feedback">
{errors.newPassword}
</div>
) : null}
</div>
</div>
</div>
</div>
<div className="row">
<div className="col-md">
<div className="form-group mb-4">
<label htmlFor="confirmNewPassword" className="cp-label">
Confirm New Password
</label>
<div className="input-group">
<Field
type={showPassword3 ? "text" : "password"}
id="confirmNewPassword"
name="confirmNewPassword"
placeholder="Confirm your New password"
className={
errors.confirmNewPassword &&
touched.confirmNewPassword
? "form-control primary-input-field is-invalid pass"
: "form-control primary-input-field pass"
}
/>
<span
className="input-group-text"
id="basic-addon2"
// onClick={() => toggleShowPassword(showPassword3)}
onClick={toggleShowPassword3}
>
{showPassword3 ? (
<VisibilityIcon
fontSize="small"
className="iconColor"
/>
) : (
<VisibilityOffIcon
fontSize="small"
className="iconColor"
/>
)}
</span>
{touched.confirmNewPassword &&
errors.confirmNewPassword ? (
<div className="invalid-feedback">
{errors.confirmNewPassword}
</div>
) : null}
</div>
</div>
</div>
</div>
<div className="row mt-4">
<div className="col text-end">
<button className="btn primary-button" type="submit">
Change Password
</button>
</div>
</div>
</Form>
)}
</Formik>
</div>
</Fragment>
);
}
const mapStateToProps = (state) => ({
changePassword: state.changePassword,
});
export default connect(mapStateToProps, {
changePassword,
})(ChangePassword);
Please someone help me to apply only one function that can toggle show and hide for three fields, I have already tried one function but it's not working. I couldn't know what to do ? I need one function there to toggle eye symbol when it is clicked, but with the function I have used it's changing and I am pressing for one field and another field's being shown, please someone explain me

Bootstrap-Vue + Vuelidate: "Dialog" for creating and updating data

I'm trying to reuse the dialog form but when trying to update Vuelidate says the form is invalid, I'm not sure why. This is my code.
<b-modal size="lg" ref="my-modal" hide-footer :title="modalTitle + ' User'">
<form #submit.prevent="onSubmit" #reset.prevent="onReset">
<b-row>
<b-col>
<b-form-input id="input-name"
v-model="form.name"
#input="$v.form.name.$touch()"
:state="$v.form.name.$dirty ? !$v.form.name.$error : null"
placeholder="Name"
trim></b-form-input>
</b-col>
<b-col>
<b-form-input id="input-email"
v-model="form.email"
#input="$v.form.email.$touch()"
:state="$v.form.email.$dirty ? !$v.form.email.$error : null"
placeholder="Email"
trim></b-form-input>
</b-col>
</b-row>
<b-row v-if="mode === 0">
<b-col>
<b-form-input id="input-password"
v-model="form.password"
#input="$v.form.password.$touch()"
:state="$v.form.password.$dirty ? !$v.form.password.$error : null"
type="password"
placeholder="Password"
trim></b-form-input>
</b-col>
<b-col>
<b-form-input id="input-password-confirm"
v-model="form.password_confirmation"
#input="$v.form.password_confirmation.$touch()"
:state="$v.form.password_confirmation.$dirty ? !$v.form.password_confirmation.$error : null"
type="password"
placeholder="Password Confirmation"
trim></b-form-input>
</b-col>
</b-row>
<b-button v-if="mode === 1"
class="mb-1"
:class="visible ? null : 'collapsed'"
:aria-expanded="visible ? 'true' : 'false'"
aria-controls="collapse-4"
#click="visible = !visible">Change Password
</b-button>
<b-collapse v-model="visible" class="mt-2">
<b-form-input id="input-password-edit"
v-model="form.password_edit"
#input="$v.form.password_edit.$touch()"
:state="$v.form.password_edit.$dirty ? !$v.form.password_edit.$error : null"
type="password"
placeholder="New Password"
trim></b-form-input>
</b-collapse>
<b-row>
<b-col>
<b-form-select :options="roles"
v-model="form.role"
#input="$v.form.role.$touch()"
:state="$v.form.role.$dirty ? !$v.form.role.$error : null"
placeholder="User Role"></b-form-select>
</b-col>
</b-row>
<b-row align-h="end" style="padding-left: 1rem; padding-right: 1rem">
<b-button class="mr-1" #click="cancel" variant="secondary">Cancel</b-button>
<b-button type="submit" variant="primary">Save</b-button>
</b-row>
</form>
</b-modal>
data() {
return {
url: '/users',
form: {
name: '',
email: '',
password: '',
password_confirmation: '',
password_edit: '',
role: ''
},
users: [],
roles: [],
}
},
validations: {
form: {
name: {
required
},
email: {
required,
email
},
password: {
required: requiredIf(this.modalTitle() === 'New')
},
password_confirmation: {
required: requiredIf(this.modalTitle() === 'New'),
sameAsPassword: sameAs('password')
},
role: {
required
},
password_edit: {
required: requiredIf(this.modalTitle() === 'Edit')
}
}
},
methods: {
create() {
this.onReset();
this.mode = 0;
this.$refs['my-modal'].show();
},
edit(item) {
this.onReset();
this.mode = 1;
this.form = _.cloneDeep(item);
this.form.role = this.form.roles[0]['id'];
this.$refs['my-modal'].show();
},
onSubmit() {
this.$v.$touch()
console.log(this.$v.invalid);
if (!this.$v.$invalid) {
if (this.mode === 0) {
this.$inertia.post(this.url, {
name: this.form.name,
email: this.form.email,
password: this.form.password,
password_confirmation: this.form.password_confirmation,
role: this.form.role,
}).then(
() => {
if (Object.entries(this.$page.props.errors).length === 0) {
this.$refs['my-modal'].hide();
this.onReset();
this.$bvToast.toast('New User Created', {
title: 'Action Successful',
variant: 'success',
toaster: 'b-toaster-top-center',
solid: true
});
}
}
)
} else {
console.log('here')
this.$inertia.put(this.url + '/' + this.form.id, {
name: this.form.name,
email: this.form.email,
role: this.form.role,
password_edit: this.form.password_edit
}).then(
() => {
if (Object.entries(this.$page.props.errors).length === 0) {
this.$refs['my-modal'].hide();
this.onReset();
this.$bvToast.toast('User Updated', {
title: 'Action Successful',
variant: 'success',
toaster: 'b-toaster-top-center',
solid: true
});
}
}
)
}
}
},
},
In the onSubmit() if I add a console.log it stops working after if (!this.$v.$invalid) which means that I'm not using Vuelidate correctly but in the validations when I try to use requiredIf I get an error
Error in created hook: "TypeError: Cannot read property 'modalTitle' of undefined"
TypeError: Cannot read property 'modalTitle' of undefined
this.modelTitle() is a computed property, I also tried doing required: requiredIf(this.mode === 1) but I get the same errors.
How can I fix it so that when creating the required fields include the password and password_confimation but when editing don't require them?
The solution is to change the validators like this, in my case to be able to edit a password a section opens up using the variable visible so only when that section is visible it will require the new password, if the section is not visible then the password doesn't require being changed.
validations: {
form: {
password: {
required: requiredIf(function (pass) {
return !this.form.id
}),
},
password_confirmation: {
required: requiredIf(function (pass) {
return !this.form.id
}),
sameAsPassword: sameAs('password')
},
password_edit: {
required: requiredIf(function (pass) {
return this.form.id && this.visible
}),
}
}
},

vee-validate in steps form

I have a problem I'm trying to learn vee-validate
to a form that has steps but the problem is like as far
as the first drop I validate correctly a field from the second step is no longer works properly or someone could help this is all component and methods i think this is scope problem but i don't now?
<template>
<div>
<div v-if="step === 1">
<input
class="form-control loginForm__input"
type="text"
:class="{'input': true, 'is-invalid': errors.has('email') }"
name="email"
v-validate="'required|email'"
placeholder="Email adress"
v-model="registration.email"
/>
</div>
<div v-if="step === 2">
<input
class="form-control loginForm__input"
:class="{'input': true, 'is-invalid': errors.has('nameFirst') }"
v-validate="'required'"
name="nameFirst"
type="text"
placeholder="name"
v-model="registration.nameFirst"
/>
<div class="LoginButton">
<button
type="button"
class="btn button__blue"
#click="nextStep();progressbarNext();"
>Continue</button>
</div>
</div>
</template>
<script>
export default {
name: "Register",
components: {
},
data: function() {
return {
step: 1,
registration: {
email: null,
nameFirst: null,
}
};
},
computed: {},
methods: {
goBack() {
if (this.step === 1) {
this.$router.push("/");
return;
}
this.step--;
},
nextStep() {
this.$validator.validateAll().then(result => {
console.log(result);
if (result) {
if (this.step === 3) {
this.showModal = true;
(this.stepBannerThree = true), (this.step = 3);
return;
}
this.step++;
if (this.step == 2) {
return (this.stepBannerOne = true);
}
if (this.step == 3) {
return (this.stepBannerTwo = true);
}
return;
}
});
},
}
};
</script> ```

Simple If return in VUE.JS method

Template won't show v-if when method return true.
I can log the username password and the failed attempt in the else section of my login method. If I try to log the loginFailed var I get loginFailed is not defined.
<template>
<div class="container-big">
<div class="container-header">
<h1>Our Login</h1>
</div>
<p v-if="loginFailed">
Login Failed
</p>
<div id="loginContainer" class="container-login">
<P>{{msg}}</p>
<input id="login" type="text" placeholder="username" v-model="username" spellcheck="false" >
<input id="key" type="password" placeholder="password" v-model="password" spellcheck="false" >
</div>
<div class="container-signin">
<button class="signin" id="go" #click="login()"></button>
</div>
</div>
</template>
<script>
export default {
name: 'Login',
data () {
return {
msg: 'This is your login',
password: '',
username: '',
loginFailed: false
}
},
methods: {
login () {
console.log(this.username);
console.log(this.password);
if (this.username !== '' && this.password === 'pass') {
this.$router.push( { name: 'dashboard', path: '/dashboard' }) }
else {
console.log('failed attempt')
this.loginFailed === true;
return this.loginFailed
}
}
}
}
</script>
What I want to do is if login failed show
<p v-if="loginFailed">
Login Failed
</p>
In the login() method, you're performing a comparison when you should actually assign a value to the loginFailed property:
this.loginFailed === true;
Change that line so that it actually assigns true to this.loginFailed:
this.loginFailed = true;
side note: You most likely don't need to return anything from login() since it's simply dealing with instance properties, you might want to remove this line:
return this.loginFailed