Reputation: 88
So for form actions, I made a class to make things cleaner, but there's a problem. Whenever any errors/success messages are set in the class, Svelte does not automatically rerender the changes.
Frontend:
<script>
import Form from '@/periphs/form'
let changePasswordForm = new Form()
changePasswordForm.form.values = {
newPassword: null,
currentPassword: null
}
changePasswordForm.params.endpoint = route('api.user.settings.security.change-password')
const changePassword = () => {
changePasswordForm.execute()
}
</script>
<div class="block">
<div class="is-size-6 has-text-weight-light">Change Password</div>
<div class="field help has-text-grey-light">
1. Use special characters. (!@#$%^&*)
<br>2. Do not reuse passwords.
<br>3. Do not use passwords that can be guessed. (Birthdays, names, numbers, etc).
</div>
<fieldset disabled={ changePasswordForm.form.processing }>
<div class="field">
<div class="control">
<label for="" class="label is-small">New Password</label>
<input bind:value={ changePasswordForm.form.values.newPassword } class:is-danger={ changePasswordForm.form.errors.newPassword } type="password" class="input is-small" placeholder="New Password">
</div>
{#if changePasswordForm.form.errors.newPassword}
<div class="help is-danger">{ changePasswordForm.form.errors.newPassword }</div>
{/if}
</div>
<div class="field">
<div class="control">
<label for="" class="label is-small">Current Password</label>
<input bind:value={ changePasswordForm.form.values.currentPassword } class:is-danger={ changePasswordForm.form.errors.currentPassword } type="password" class="input is-small" placeholder="Current Password Password">
</div>
{#if changePasswordForm.form.errors.currentPassword}
<div class="help is-danger">{ changePasswordForm.form.errors.currentPassword }</div>
{/if}
</div>
<div class="field">
<button on:click={ () => changePassword() } class="button is-primary is-small">Change Password</button>
{#if changePasswordForm.form.success.message}
<div class="help is-success">{ changePasswordForm.success.message }</div>
{/if}
{#if changePasswordForm.form.errors._flood}
<div class="help is-danger">{ changePasswordForm.errors._flood }</div>
{/if}
</div>
</fieldset>
</div>
Form.js:
'use strict'
import axios from "axios"
export default class Form {
constructor() {
this.form = {
processing: false,
success: {},
errors: {},
values: {}
}
this.params = {
method: 'POST',
endpoint: null,
}
}
getErrors() {
return this.form.errors
}
execute() {
/*
Before form submission, reset all errors/successes
*/
this.form.processing = true
this.form.success = {}
this.form.errors = {}
if (this.params.method == 'POST') {
axios.post(this.params.endpoint).then(r => {
/*
Handle success
*/
this.form.errors = {}
this.form.success = r.data
}).catch(e => {
/*
422
Form errors (Validation)
*/
if (e.response.status == 422) {
this.form.errors = e.response.data.errors
}
/*
429
Request timeout (Flood)
*/
if (e.response.status == 429) {
this.form.errors = { ...this.form.errors, ...{ '_flood': e.response.data.message } }
}
console.log(this.form.errors) // SHOWS ERRORS AS ITS SUPPOSED TO, BUT THIS IS NOT REPRODUCED ON THE FRONTEND
}).finally(() => {
this.form.processing = false
})
}
}
}
Whenever there is an error/success, it should show those changes on my front end, but that is not the case. Any one got any idea on how to fix this?
Upvotes: 1
Views: 385
Reputation: 185225
Reactivity only works for code within components, outside you need to use stores or events to signal changes.
Upvotes: 4