I have got data like this:
data: () => ({
input: {
username: "",
password: ""
}
}),
and make a post request like this:
loggin_in() {
if (this.input.username != "" && this.input.password != "") {
console.log(this.input.username);
axios
.post("http://localhost:5000/login", {
email: this.input.username,
password: this.input.password
})
.then(function(data) {
console.log(data);
})
.catch(function(error) {
console.log(this.input.username);
});
}
}
Logging the first this.input.username works, but after that, I have no idea how to access the data. this seems to be undefined.
Uncaught (in promise) TypeError: Cannot read property 'input' of undefined
I dont know why the context of this changes here and don´t get how to access my data. Can anybody explain me whats going on and help me with this?
In the callback you have to bind this or use an arrow function:
.then(function(data) {
console.log(data);
})
to
.then((data) => {
console.log(data);
console.log(this);
})
Related
first of all i want to apologize for my title. I just dont know how to describe my problem.
I am trying to get a bad response from my server and when I try to display that my object is undefined
I have a base query methods here:
export const accountSlice = apiSlice.injectEndpoints({
endpoints: builder => ({
login: builder.mutation({
query: credentials => ({
url: 'account/login',
method: 'POST',
body: { ...credentials },
})
}),
register: builder.mutation({
query: credentials => ({
url: 'account/register',
method: 'POST',
body: { ...credentials },
})
})
})
})
My handle submit on register page ->
const [register, { isLoading, isError }] = useRegisterMutation();
const handleSubmit = async (e) => {
e.preventDefault();
try {
const result = await register({ name, nickName, email, password }).unwrap();
setRegisterResponse(result);
} catch (error) {
setRegisterResponse(error);
}
}
And my logic to show it. When i use console.log(registerResponse) it returnes two logs in console - first object is empty, second object with properties ->
{
isError &&
<h2>
Ooops.. something went wrong:
{
console.log(registerRespnse)
}
</h2>
}
Error in google console
You shouldn't need to call a setRegisterResponse state setter, because that response will just be available for you:
// see data and error here
const [register, { isLoading, isError, data, error }] = useRegisterMutation();
As why it logs undefined once: first the query finishes with an error (which will rerender the component and already fill error I showed above and set isError) and then the Promise resolves and your custom code sets your response local state, which causes a second rerender (and only on the second render, response is set)
I have been trying to extract a token from say http://test.com/confirm?token=MMsndiwhjidh... and then send a post request to another server.
I have tried this:
export default {
data() {
return {
confirmation : false,
somethingWrong: false
}
},
created: function() {
axios.post('/confirm', null, {
method: 'post',
params: {
token:this.$route.query.token
}
})
.then(function(res) {
console.log(res)
this.confirmation = true
})
.catch(function(error) {
console.log(error)
this.somethingWrong = true
})
}
}
I got the following errors:
I think I am not able to extract the token properly.
The reason is you're using declarative functions instead of arrow functions in your then / catch blocks. The this don't refer to the same thing (here, this is not your Vue component).
Try like this:
.then((res) => {
console.log(res)
this.confirmation = true
})
I won't try to explain the difference myself as there are plenty of articles on the web about it. Here's one
I'm raising the white flag and asking for suggestions even though I feel the answer is probably right in front of my face.
I have a login form that I am submitting to an api (AWS) and acting on the result. The issue I am having is once the handleSubmit method is called, I am immediately getting into the console.log statement... which to no surprise returns dispatch result: undefined
I realize this is likely not a direct function of vue.js, but how I have the javascript set executing.
Here is my login component:
// SignInForm.vue
handleSubmit() {
try {
const {username, password} = this.form;
this.$store.dispatch('user/authenticate', this.form).then(res => {
console.log('dispatch result: ', res);
});
} catch (error) {
console.log("Error: SignInForm.handleSubmit", error);
}
},
...
Here is what my store is doing. I'm sending it to a UserService I've created. Everything is working great. I am getting the correct response(s) and can log everything out I need. The UserService is making an axios request (AWS Amplify) and returning the response.
// user.js (vuex store)
authenticate({state, commit, dispatch}, credentials) {
dispatch('toggleLoadingStatus', true);
UserService.authenticate(credentials)
.then(response => {
dispatch('toggleLoadingStatus', false);
if (response.code) {
dispatch("setAuthErrors", response.message);
dispatch('toggleAuthenticated', false);
dispatch('setUser', undefined);
// send error message back to login component
} else {
dispatch('toggleAuthenticated', true);
dispatch('setUser', response);
AmplifyEventBus.$emit("authState", "authenticated");
// Need to move this back to the component somehow
// this.$router.push({
// name: 'dashboard',
// });
}
return response;
});
},
...
Where I'm getting stuck at is, if I have error(s) I can set the errors in the state, but I'm not sure how to access them in the other component. I've tried setting the data property to a computed method that looks at the store, but I get errors.
I'm also struggling to use vue-router if I'm successfully authenticated. From what I've read I really don't want to be doing that in the state anyway -- so that means I need to return the success response back to the SignInForm component so I can use vue-router to redirect the user to the dashboard.
Yep. Just took me ~6 hours, posting to SO and then re-evaluating everything (again) to figure it out. It was in fact, somewhat of a silly mistake. But to help anyone else here's what I was doing wrong...
// SignInForm.vue
async handleSubmit() {
try {
await this.$store.dispatch("user/authenticate", this.form)
.then(response => {
console.log('SignInForm.handleSubmit response: ', response); // works
if (response.code) {
this.errors.auth.username = this.$store.getters['user/errors'];
} else {
this.$router.push({
name: 'dashboard',
});
}
}).catch(error => {
console.log('big problems: ', error);
});
} catch (error) {
console.log("Error: SignInForm.handleSubmit", error);
}
},
...
Here's my first mistake: I was calling from an async method to another method - but not telling that method to be async so the call(er) method response was executing right away. Here's the updated vuex store:
// user.js (vuex store)
async authenticate({state, commit, dispatch}, credentials) { // now async
dispatch('toggleLoadingStatus', true);
return await UserService.authenticate(credentials)
.then(response => {
console.log('UserService.authenticate response: ', response); // CognitoUser or code
dispatch('toggleLoadingStatus', false);
if (response.code) {
dispatch("setAuthErrors", response.message);
dispatch('toggleAuthenticated', false);
dispatch('setUser', undefined);
} else {
dispatch('toggleAuthenticated', true);
dispatch('setUser', response);
AmplifyEventBus.$emit("authState", "authenticated");
}
return response;
});
},
...
My second error was that I wasn't returning the result of the method at all from the vuex store.
Old way:
UserService.authenticate(credentials)
Better way:
return await UserService.authenticate(credentials)
Hope this saves someone a few hours. ¯_(ツ)_/¯
This works for Vue3:
export default {
name: 'Login',
methods: {
loginUser: function () {
authenticationStore.dispatch("loginUser", {
email: 'peter#example.com',
})
.then(response => {
if (response.status === 200) {
console.log('Do something')
}
});
},
},
}
In the store you can simply pass back the http response which is a promise.
const authenticationStore = createStore({
actions: {
loginUser({commit}, {email}) {
const data = {
email: email
};
return axios.post(`/authentication/login/`, data)
.then(response => {
toastr.success('Success')
return response
})
},
}
})
i got a frisby function
createPOST = function () {
return frisby.post(url, {
body: qs.stringify({
username: data.user,
password: data.password
}),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then((resp) => {
let respJson = resp.json;
return respJson;
}, (error) => {
console.error("Error:: " + error);
throw error;
});
}
and second function
getRespJson = function () {
createToken().then(function (value) {
console.log("resp::"+value);
});
}
im trying to retrieve this json response in another function, but not able to using frisby. no log is even displaying
If your data coming in the body(that you are expecting) or anywhere, simply store into other variable and then by nested way you able to use it. if you have multiple nested body then in that situation you also able to use it.
I'm using the same with that workaround.
or try to use it by storing that into another file.
Thanks
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 4 years ago.
Am using a vuejs app with laravel but i cant really get the component from the object what should i do
<script>
import axios from 'axios';
export default {
data : function (){
return {
email: '',
password: '',
remember: 'true',
errors: [],
}
},
methods : {
validateemail(mail){
var re = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(mail);
},
attemptlogin(){
this.errorsarray = [];
axios.post('/login', {
email: this.email,
password: this.password,
remember : this.remember
}).then(function (response) {
location.reload();
}).catch(function (error) {
var code = error.response.status;
console.log(this.email);
if(code == 422){
this.errors.push("Incorrect information");
}else{
console.log('no');
this.errors.push('Internal server error please try again later')
}
}).then(function () {
console.log('here');
});
},
},
computed : {
isValidInput() {
return this.validateemail(this.email) && this.password;
}
}
}
it also display this kind of error
Uncaught (in promise) TypeError: Cannot read property 'email' of undefined
I dont know why anyhelp ?
thanks in advance
Use () => {} function syntax instead of function() {}. The former will bind this correctly.
.catch(error => {
console.log(this.email);
})
If you want to use function() {} then you must explicitly bind this:
.catch(function (error) {
console.log(this.email);
}.bind(this))
See this answer for more information about bind.