Nuxt.js page reloading on for submission even with stop.prevent - javascript

I've been reading some questions about this exact same topic like but none of them seems to be working for me and I can't spot the error.
I have this form:
<template>
<div class="container">
<form #submit.stop.prevent="submit">
<input v-model="name" type="text" />
<input v-model="email" type="text" />
<button type="submit">Submit</button>
</form>
</div>
</template>
And the following script
<script>
export default {
data() {
return {
name: '',
email: ''
}
},
methods: {
async submit() {
const res = await this.$axios.request({
url: 'locahost:3000/404', // This route doesn't exists
method: 'post',
data: this.$data
})
console.log(res.status)
}
}
}
</script>
As you can see, there are more than one input in the form and I'm using stop.prevent when binding the submit event in the form.
I want to treat any possible errors in the axios request in the script part and update the page based on that (showing an error div or whatever) but without reloading it. However, the page reloads and is going to a 404 error page.
I'm using Nuxt 2.12.2 and I can't see what I'm doing wrong. Any help would be appreciated.
Thanks all!

You can omit the form behaviour by only using the data in your submit method and trigger it by #click on the button without any submit type, like this :
<template>
<div class="container">
<form>
<input v-model="name" type="text" />
<input v-model="email" type="text" />
<button #click="() => submit()">Submit</button>
</form>
</div>
</template>
Like this you will avoid any kind of side effect from the form as you don't need any form data in your axios request...

Ok, I found the answer just by trial and error and it was easier than I thought... It was only about unhandled promise rejection. As I'm using async/await I need to treat exceptions correctly and I was not doing that, the rejection was being propagated and the error handled by nuxt. So changing my code to:
<script>
export default {
data() {
return {
name: '',
email: ''
}
},
methods: {
async submit() {
try {
const res = await this.$axios.request({
url: 'locahost:3000/404', // This route doesn't exists
method: 'post',
data: this.$data
})
console.log(res.status)
} catch (err) {
console.log(err)
}
}
}
}
</script>
That will prevent the error to be handled elsewhere and resulting in a redirection to a 404 page or whatever.

Related

SvelteKit: cookies.set() In Form Action Not Working

I am trying to implement JWT-based user sessions with SvelteKit, and have mostly been following the explanation for form actions given on their website: https://kit.svelte.dev/docs/form-actions
+page.svelte
<form method="POST" action="?/signIn">
<input type="text" name="name" />
<input type="password" name="password" />
<button type="submit">Submit</button>
</form>
+page.server.svelte
import { fail, redirect } from "#sveltejs/kit";
import { signIn } from "$lib/server/database";
export const actions = {
signIn: async ({ cookies, request }) => {
const data = await request.formData();
const name = data.get("name");
const password = data.get("password");
if (!name || !password) {
return fail(400);
}
try {
cookies.set("jwt", await signIn(name, password));
} catch (error) {
return fail(400);
}
throw redirect(303, "/");
},
};
I have tested my signIn method which I import and use here, and it does return a token when called with the correct credentials. So far, so good. However, I noticed that I don't see any cookies in my developer tools. It seems like the cookies.set() call simply does nothing. I'd like to set the returned JWT as a cookie so that I can authenticate my users, so what am I doing wrong?
In case anybody else has this problem: While the cookie was set as it was supposed to when using Chrome, it wasn't in Safari. I solved this by setting the secure option to false, even though the SvelteKit docs state that this is done automatically on localhost.

Email.js Works Locally, But not Once Deployed With React

I have set up Email.js to make a contact page for a website built with Next.js. It works completely fine when run locally, but does not work when hosted. The form does not even reset when the submit button is clicked. I do this in the sendEmail function. The error handler does not trigger either in the .then block. I get this error in the browser console:
Uncaught The user ID is required. Visit https://dashboard.emailjs.com/admin/integration
Here is how I send the emails:
export default function Book(props) {
const form = useRef();
const [sentMessage, setSentMessage] = useState();
const sendEmail = (e) => {
e.preventDefault();
emailjs
.sendForm(
props.SERVICE_ID,
props.EMAIL_TEMPLATE_ID,
form.current,
props.USER_ID
)
.then(
function (response) {
setSentMessage("Message sent successfully!");
},
function (error) {
setSentMessage("Message failed please email directly.");
}
);
document.getElementById("form").reset();
};
return (
<div className={styles.container}>
<div className={styles.formContainer}>
<form
className={styles.form}
ref={form}
onSubmit={sendEmail}
id="form"
>
<h3>Name (required):</h3>
<input type="text" required={true} name="user_name"></input>
<h3>Email (required):</h3>
<input type="email" required={true} name="user_email"></input>
<h3>Phone number (required):</h3>
<input type="number" required={true} name="phone_number"></input>
<h3>Message (optional):</h3>
<textarea name="message"></textarea>
<button type="submit" value="Send">
Submit
</button>
{sentMessage ? <p>{sentMessage}</p> : <p></p>}
</form>
</div>
</div>
);
}
export async function getServerSideProps() {
return {
props: {
USER_ID: process.env.USER_ID,
EMAIL_TEMPLATE_ID: process.env.EMAIL_TEMPLATE_ID,
SERVICE_ID: process.env.SERVICE_ID,
},
};
}
I have a .env.local file with the template id, user id and service id that all work fine locally. I use next-env and dotenv-load in the next.config.js file like so:
dotenvLoad();
const withNextEnv = nextEnv();
module.exports = withNextEnv({
reactStrictMode: true,
webpack(config) {
config.module.rules.push({
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
use: ["#svgr/webpack"],
});
return config;
},
});
I saw some problems online that people had with Gmail and remote email servers, so I switched the account to have no 2 factor authentication and use less secure apps as well. That had no effect.
All you need to do is set up the environment variables in the next.js dashboard then rebuild the site so they take effect.

Watching for form data in nuxtjs

On my page I have a form,
<div v-if="this.userdata.address == ''">Please enter your address</div>
Your address
<input type="text" v-model="userdata.address">
Your phone
<input type="text" v-model="userdata.phone">
Your message
<input type="text" :disabled="this.userdata.address == '' ? true : false">
And my script section is:
<script>
export default {
data() {
return {
userdata: {
companydata: {}
}
}
}
}
.....
<script>
If my user is Authorized, "userdata" data will be filled in fetch().
My problem is to check, if address field filled in or not on the go, and then if user entered his address, make Message field active, but if he not filled it, or cleaned this field (if he authorized and data was loaded to form in fetch() method), make Message field disabled again.
Problem is that if I reload this page, everything is works, but if I navigate to it from other page, nothing is works.
Whats a problem can be?
I was missing the address data in my userdata. I managed to fix my problem simply by adding it as an empty string.
<script>
export default {
data() {
return {
userdata: {
address: "", //// Adding this solved my problem
companydata: {}
}
}
}
}
.....
<script>

Vue template won't render if array in data function is empty

I'm having a problem with a Vue template where no elements on the page will not render unless an array declared on data is already populated.
The problem is that the data is only populated after an API call made by submitting a form.
The browser console reads Error in render: "TypeError: Cannot read property 'response' of undefined"
If I comment out the {{classes.data.response}} the form displays but will not otherwise.
Here is what the code looks like.
<template>
<div class="container">
<form #submit="getClass">
<input type="text" placeholder="Search..." v-model="class_id">
<button type="submit">Search</button>
</form>
<br>
<div v-if="classes"> <!-- conditionally render if array has results -->
{{classes.data.response}} <!-- form shows when this is commented out -->
</div>
</div>
</template>
The data block
data() {
return {
classes: []
};
},
...
And the methods block
methods: {
...
// Request
axios(config)
.then(response => (this.classes = response))
.catch(function (error) {
console.log('There was an error :' , error);
});
}
}
I'm relatively new to Vue so if anyone can tell me what is going wrong here I'd much appreciate it. Thanks in advance!
this.classes.data.response is not defined
You can try to be more specific when assigning the response to classes. Instead of this.classes = response, do this this.classes = response.data.response. response.data.response is the Array you are looking for, not response.
methods: {
...
// Request
axios(config)
.then(response => (this.classes = response.data.response))
.catch(function (error) {
console.log('There was an error :' , error);
});
}
}
Then in the template just write {{ classes }} instead of {{ classes.data.response }}, also v-if="classes.length > 0" instead of just v-if="classes".
v-if="classes" will always be true
v-if="classes.length > 0" will be true when the Array has more the 0 elements in it
Why
Because of the asynchronous nature of the API request, the moment the form tries to render this.classes will still be the empty Array you defined. Only later, once the API request has finished, this.classes will have the data it needs.
empty arrays are truthy, so v-if="classes" will always be true. use classes.length, as an empty array will result in 0 which is falsy.
maybe yo can do something like
<div v-if="classes.length>0">
{{classes.data.response}}
</div>

Netlify Forms - Empty Submission - Vue (Gridsome)

I hate to do this (share the whole code), but I feel like I have no other choice. I have been banging my head against the wall for the past two days. It is one issue after another. Currently, I am soooo close to getting Forms working.
For some reason an empty field is submitted. I can't find the reason, it is really hard to debug.
<template>
<form
name="add-subscriber"
id="myForm"
method="post"
data-netlify="true"
data-netlify-honeypot="bot-field"
#submit.prevent="handleFormSubmit">
<input type="hidden" name="form-name" value="add-subscriber" />
<input type="email" name="email" v-model="formData.userEmail">
<button type="submit" name="button">Subscribe</button>
</form>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
formData: {},
}
},
methods: {
encode(data) {
return Object.keys(data)
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`)
.join("&");
},
handleFormSubmit(e) {
const axiosConfig = {
header: { "Content-Type": "application/x-www-form-urlencoded" }
};
axios.post(
location.href,
this.encode({
'form-name': e.target.getAttribute("name"),
...this.formData,
}),
axiosConfig
)
.then(data => console.log(data))
.catch(error => console.log(error))
.then(document.getElementById("myForm").innerHTML = `<div>Almost there! Check your inbox for a confirmation e-mail.</div>`)
}
}
}
</script>
If there is anything that comes to mind or jumps at you, I would really appreciate your help! Thanks a ton in advance.
P.S. I used the guides from Netlify and CSS-Tricks
Edit
The Params of my POST request seem legit:
-----------------------------171747581031589150472368446206
Content-Disposition: form-data; name="form-name"
add-subscriber
-----------------------------171747581031589150472368446206
Content-Disposition: form-data; name="userEmail"
me#rasul.com
-----------------------------171747581031589150472368446206--
However, the response is a little weird. It is returning the whole page, for some reason:

Categories