I have a code to do login task:
onSubmit() {
this.$q.loading.show();
this.$axios.post("http://localhost/adminision/api/usermanager/login.php",
{
language: "vi",
instituteid: this.$store.state.mainState.istituto,
username: this.username,
password: this.passwd
}).then((t => {
1 == t.data.success ? (this.$store.commit("mainState/setLoginData", t.data.token), this.$store.commit("mainState/setFirstName", t.data.firstName), this.$store.commit("mainState/setLastName", t.data.lastName), this.$store.commit("mainState/setMatrixID", "login"), this.$q.sessionStorage.set("token", t.data.token), this.$router.push({
path: "/dashboard"
})) : (this.$q.loading.hide(), this.validatormessage = "Username or password not valid", this.mostraerrori = !0)
})).catch((t => {
this.validatormessage = t.response.data.error.description, this.mostraerrori = !0
}))
},
But when i click submit button, this.$axios.post runs, but nothing happens. No login.php appear in Network tab of Chrome browser, with no js error. I've set breakpoint in catch body but it is unreachable.
So, please help, what can i do ?
You have syntax error in your code. Each line should have been ended with semicolon instead of comma or If you leave it javascript ASI will auto insert it:
onSubmit() {
this.$q.loading.show();
this.$axios.post("http://localhost/adminision/api/usermanager/login.php", {
language: "vi",
instituteid: this.$store.state.mainState.istituto,
username: this.username,
password: this.passwd
}).then((t => {
if (t.data.susccess === 1) {
this.$store.commit("mainState/setLoginData", t.data.token);
this.$store.commit("mainState/setFirstName", t.data.firstName);
this.$store.commit("mainState/setLastName", t.data.lastName);
this.$store.commit("mainState/setMatrixID", "login");
this.$q.sessionStorage.set("token", t.data.token);
this.$router.push({
path: "/dashboard"
})
} else {
this.$q.loading.hide();
this.validatormessage = "Username or password not valid";
this.mostraerrori = !0;
}
})).catch((t) => {
this.validatormessage = t.response.data.error.description;
this.mostraerrori = !0;
})
},
Related
I am trying to handle validation errors of my laravel API with rect.
A strange thing happens to me when I try to validate the form for submitting data, it is as if the states of react are not updated correctly.
This is the code I use for validation process.
I have react states for handling error messages for each field in the form:
const [errors,setErrors] = useState({
'name': null,
'email': null,
});
useEffect(() => {
console.log(errors)
}, [errors]);
const handleErrors = (messages) => {
// {"name":["Inserire il nome azienda"],"email":["The email must be a valid email address."]}
Object.keys(messages).forEach(el => {
console.log("Element: " + el)
console.log("Message: " + messages[el][0])
setErrors({
...errors,
[el]: messages[el][0]
})
});
}
const handleSubmit = () => {
flushSync(() => {
setErrors({
'name': null,
'email': null,
});
})
api.post("organization", organization)
.then(response => {
})
.catch(reason => {
if (reason.response.status === 422)
{
handleErrors(reason.response.data.errors);
}
});
}
The application requires that the name field be mandatory, while the email field is either null or a valid email.
This is the console output with both fields blank (correct):
// this is from use effect print
{name: null, email: null}
POST http://localhost/api/v2/organization 422 (Unprocessable Content)
add.jsx:70 Element: name
add.jsx:71 Message: Inserire il nome azienda
// this is from use effect print
add.jsx:51 {name: 'Inserire il nome azienda', email: null}
This is from with a valid name and an INVALID email:
// this is from use effect print
{name: null, email: null}
POST http://localhost/api/v2/organization 422 (Unprocessable Content)
add.jsx:70 Element: email
add.jsx:71 Message: The email must be a valid email address.
// this is from use effect print
add.jsx:51 {name: 'Inserire il nome azienda', email: 'The email must be a valid email address.'}
It appears that the state is maintained with the previous one.
I have a simple setup for validating a few form entries. It only pushes validation for the first entry. So in state I have:
this.state = {
username: '',
email: '',
zip: '',
errors:[]
}
The submit button:
<div>
<button onClick={this.handleSubmit}
>submit
</button>
</div>
The submit button and the form both trigger handleSubmit:
handleSubmit(e) {
e.preventDefault();
this.setState({errors:[]});
const {username, email, zip} = this.state;
const errors = validate(username, email, zip);
if (errors.length>0) {
this.setState({errors});
}
}
which hits validate:
function validate(username, email, zip) {
let validEmail = RegExp(/[^# \t\r\n]+#[^# \t\r\n]+\.[^# \t\r\n]+/);
let validZip = RegExp(/^\d{5}$/);
const errors = [];
if (username.length < 3 || null) {
errors.push('Name must be at least 3 characters long.');
}
if (validEmail.test(email)) {
errors.push('Email address must be valid email address.');
}
if (validZip.test(zip)) {
errors.push('Zip code must be 5 digits.')
}
console.log(errors);
return errors;
}
and then, from the updated state, errors are supposed to print as line items in:
<ul className="errorList">
{this.state.errors.map(
(error =>
<li key={error}>
{error}
</li>
)
)}
</ul>
but only the first validation is working (for username), in a console log and in the unordered list.
Looking for advice ^~^
validEmail.test(email) return false, try !validEmail.test(email) will return true if email failed
I have created a settings page where users can update their email addresses. Everything worked fine but suddenly the validation is not updating anymore. Only the first change of the input field triggers validateState().
Any further changes will not trigger this function so the status of that field stays as it is.
I have compared the code with other components that use the same code and they still work fine.
I am using bootstrap-vue components for the form.
<template>
<div class="row">
<div class="col-md-12">
<b-form #submit="onSubmit">
<b-form-group :label="$t('general.email')"
label-for="settingsEmail"
:invalid-feedback="errors.first('email')">
<b-form-input id="settingsEmail"
type="text"
v-model="form.email"
:disabled="saving"
name="email"
:state="validateState('email')"
v-validate="{required: true, email: true}">
</b-form-input>
</b-form-group>
<b-button type="submit" variant="primary" :disabled="saving || !hasChanged() || errors.any()"><i class="fa fa-refresh fa-spin fa-fw" v-if="saving"></i> {{$t('general.save')}}</b-button>
</b-form>
</div>
</div>
</template>
<script>
import {UPDATE_USER} from '../config/actions'
export default {
name: 'settingsAccount',
data() {
return {
form: {},
saving: false
}
},
computed: {
user: function() {
return this.$store.getters.getUser;
}
},
created() {
this.init();
},
methods: {
init() {
this.form.email = this.user.email;
},
hasChanged() {
if(this.form.email !== this.user.email) {
return true;
}
return false;
},
onSubmit(event) {
event.preventDefault();
this.saving = true;
this.$validator.validateAll().then((result) => {
if (result) {
let data = {};
if(this.form.email !== this.user.email) {
data.email = this.form.email;
}
this.$store.dispatch(UPDATE_USER, data).then(() => {
this.saving = false;
this.$validator.reset();
}).catch(() => {
this.saving = false;
});
} else {
this.saving = false;
}
});
},
validateState(ref) {
if (this.veeFields[ref] && (this.veeFields[ref].dirty || this.veeFields[ref].validated)) {
return !this.errors.has(ref)
}
return null
},
}
}
</script>
The problem you're having is that the form data element is an empty object, so it will only trigger reactivity when the whole object changes. Either you need to change your data to be this:
data() {
return {
form: {email:''},
saving: false
}
},
Or in your init function, explicitly add the email property as reactive:
methods: {
init() {
this.$set(form,'email',this.user.email)
},
//...
If you're not clear on why, you can read the details here: https://v2.vuejs.org/v2/guide/reactivity.html
A working example (minus vuex) here: https://codesandbox.io/s/x4kp93w3o
PS, when writing questions about vue, it's very helpful to boil it down to a simpler example. Get rid of vuex, remove your translation stuff. Sometimes the answer will jump out at you once you have it as simple as possible.
below is HTML code for form
<div class="form-group">
<label for="email">Email</label>
<input type="email" class="form-control"
(blur)="suggestEmail(signupForm.controls['userData'].controls.email.value)"
id="email" formControlName="email">
<span class="help-block" *ngIf="!signupForm.get('userData.email').valid && signupForm.get('userData.email').touched">
please enter a valid email id
</span>
</div>
Below is ts code
constructor(private fb: FormBuilder) {
this.signupForm = this.fb.group({
userData: this.fb.group({
email: [null, [Validators.required, Validators.email]]
})
});
}
ngOnInit() {
}
suggestEmail(email) {
Mailcheck.run({
email: email,
domains: ['gmail.com', 'aol.com', 'hotmail.com', 'yahoo.com', 'rediffmail.com', 'edu', 'msn.com',],
secondLevelDomains: ['domain', 'hotmail'],
topLevelDomains: ["com", "net", "org", "info"],
suggested: function (suggestion) {
console.log(suggestion);
if (suggestion) {
alert(suggestion.full);
console.log(suggestion.full + "dkdjdekjekde")
}
},
empty: function () {
}
});
}
Right now, value of suggestions.full comes in alert if its being called. But I am trying to show suggestions.full in html side, like as a error warning.
Below is link to my stackblitz
stackblitz
To avoid potential problems with access to this within the Mailcheck.run suggested callback, you could save the results of Mailcheck.run, check them and, if appropriate, set an error on your form field.
let check = Mailcheck.run({
email: email,
... other stuff ...
suggested: (suggestion) => {
return suggestion;
},
empty: () => {
return false; // or however you want to handle it...
}
if (check && check.full) {
this.suggestedEmail = check.full;
this.signupForm.get('userData.email').setErrors({ 'has_suggestion': true })
}
// then in your template (using a getter)
<span class="help-block"
*ngIf="f.invalid && f.touched && f.errors?.has_suggestion">
Suggestion: {{suggestedEmail}}
</span>
Please find this stackblitz -- hope it helps!
Instead of using a regular function which will be lost this scope whereas arrow function keeps track of this. Read more about the difference here https://stackoverflow.com/a/34361380/5836034
do something like this
....
suggestion: any;
....
suggestEmail(email) {
Mailcheck.run({
email: email,
domains: ['gmail.com', 'aol.com', 'hotmail.com', 'yahoo.com', 'rediffmail.com', 'edu', 'msn.com',],
secondLevelDomains: ['domain', 'hotmail'],
topLevelDomains: ["com", "net", "org", "info"],
suggested: (suggestion) => {
console.log(suggestion);
if (suggestion) {
alert(suggestion.full);
this.suggestion = suggestion;
console.log(suggestion.full + "dkdjdekjekde")
}
},
empty: function () {
}
});
}
Observe the use of arrow function, to keep track of this scope and also, assigning the value of suggestion to your class variable via
this.suggestion = suggestion
in your template, you can now have access to suggestion like so
<div *ngIf="suggestion">{{suggestion.full}} </div>
Source: https://stackblitz.com/edit/angular-email-checker-bjcrcc
In my blog-like Vue.js app, the posts are rendered in a v-for loop. When a button under each post is clicked, its comments are fetched from the server and attributed like this, as post objects have no comments attribute:
`this.$set(post, 'comments', res.data.comments) ;`
The code to render the comments is this:
<div v-for="(c, j) in post.comments" :key="j">
<span>{{c.body}}</span>
<span v-if="post.user_id==userId" #click="delComment(c, post)">Delete me!</span>
</div>
And the deleteing method:
delComment(c, post) {
const payload = {
token: this.token,
cid: c.id
}
axios.delete(this.BASE_URL + "/api/comment", { data: payload } )
.then( (res)=> {
post.comments = this.post.comments.filter((comment)=>{
return comment.id != c.id
});
this.$set(post, 'comments', post.comments) ;
})
.catch( error => {
console.log(error);
});
},
But when I click the Delete link, I get this error in the console:
TypeError: Cannot read property 'comments' of undefined
at eval (Home.vue?76f2:540)
How can I fix this?
You're missing this before post :
//v-------------//here
this.post.comments = this.post.comments.filter((comment)=>{
return comment.id != c.id
});
and here :
//----------v--------------------v
this.$set(this.post, 'comments', this.post.comments) ;
Update :
i was assuming that you a property called post in your data object as follows:
data(){
return{
post:[]
...
}
}
so in this case you should remove any this before post variable.
Alright, I realized that the culprit was an extra this in this.post.comments.filter((comment).
The working code is this:
delComment(c, post) {
const payload = {
token: this.token,
cid: c.id
}
axios.delete(this.BASE_URL + "/api/comment", { data: payload } )
.then( (res)=> {
post.comments = post.comments.filter((comment)=>{
return comment.id != c.id
});
this.$set(post, 'comments', post.comments) ;
})
.catch( error => {
console.log(error);
});
},
Thanks guys for sharing your thoughts!