Vue - how can i call another method from a callback? [duplicate] - javascript

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 1 year ago.
I need to call the function get_data() once the function save_key() is done executing, the problem is that i get a Cannot read property 'get_data' of undefined error. I assume i'm getting it because the function is called from a callback. How can i solve this?
methods: {
async get_data(){
var response = await axios.get("http://127.0.0.1:8000/retrieve_user_data");
this.keys = response['data']
},
save_key(){
var key_data = {'action': 'save', 'key': this.form.key}
return axios({
method: 'post',
url: 'http://127.0.0.1:8000/save_data/',
data: key_data,
withCredentials: true,
headers: {}
}).then(function (response) {
this.get_data()
})
}
}

The error is because the scope of 'this' is set to global(window) object in your callback. This can be solved by using arrow function or using a placeholder variable for this. You can try and update your save_key function like this
save_key(){
const self = this;
var key_data = {'action': 'save', 'key': this.form.key}
return axios({
method: 'post',
url: 'http://127.0.0.1:8000/save_data/',
data: key_data,
withCredentials: true,
headers: {}
})
.then(function (response) {
self.get_data();
})
}

Related

TypeError: this.abc is not a function | javascript

Not a fronted or JavaScript so not able to understand why it's not able to find the defined function in the file. I am integrating Apple Pay and I am trying to call the back-end API based on certain event. Here is my code.
ACC.payDirect = {
_autoload: ['payDirect'],
session: null,
payDirect: function () {
let button = $('#mbutton');
if (button.length === 0) {
return;
}
$('#mbutton').on('click', this.onButtonClicked.bind());
},
onButtonClicked: function () {
if (!Session) {
return;
}
var request = getCartPaymentRequest();
this.requestSession("1234"); //getting error while calling this function
session.begin();
},
requestSession: function (validationURL) {
return new Promise(function (resolve, reject) {
$.ajax({
type: 'POST',
url: ACC.config.encodedContextPath + '/checkout/request_session',
data: JSON.stringify({ validationURL: validationURL }),
dataType: 'json',
contentType: 'application/json',
success: resolve,
error: reject
});
});
},
},
function getCartPaymentRequest() {
var result = "";
$.ajax({
type: 'GET',
url: ACC.config.encodedContextPath + '/checkout/payment-request',
dataType: 'json',
async: false,
success: function (response) {
result = response;
},
});
return result;
}
While calling the requestSession I am getting the following error
TypeError: this.requestSession is not a function. (In 'this.requestSession("1234")', 'this.abc' is undefined)
I am sure doing some basic mistake but not able to find out the root cause as why it's not able to find the second function while the first one seems to be working without any issue.
The problem is with the .bind method you called without any parameters.
Take the following example:
const obj2 = {
b: function (callback) {
callback()
}
};
const obj = {
a: function () {
obj2.b(this.c.bind())
},
c: function () {
console.log(this)
}
};
obj.a()
What will happen here is that the Window object will appear in the console.
This happens because the window is somewhat of the global context, and when running in the browser JavaScript's bind's parameter will default to the only context it can: the window.
What you need to do is call the .bind method using the ACC.payDirect as parameter as it will then bind it to the object and use the proper context, you could use a this but if the methodm was called with a different context would cause problems. An even better solution (provided you can use new ES features) is using arrow functions. They are much, much better to work with and won't give you headaches such as this.

this.$emit is not a function within ajax success request [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 1 year ago.
I have the code below:
remove Dog: function(dog) {
self = this;
const updated = this.pets.filter(o => o !== dog);
$.ajax({
type: "PATCH",
url: //irrelevant,
'data': //irrelevant,
'dataType': 'json',
success: function (result) {
self = this;
this.$emit('update:pets', updated);
},
error: function (result) {
}
});
}
I am trying to have an emit command after the success of the ajax request. The ajax works fine so don't worry about that. I am just unable to do the emitting because it says that this.$emit is not a function.
Can anyone help?
this property has access to your scope level properties because it's a function and not an arrow function. So when you access the properties or method which is not in the scope of that function, it returns undefined or not a function.
To fix it, Make your success function as an arrow function of Javascript.
success: (result) => {
this.$emit('update:pets', updated);
},
Another way is to remove the self inside the success method and use the outer self.
success: function (result) {
self.$emit('update:pets', updated);
},

Not using one of the parameters in a method [duplicate]

This question already has answers here:
Skipping optional function parameters in JavaScript
(4 answers)
Closed 7 years ago.
Total noob question but say if created a function called sendRequest that takes in a couple of parameters for an ajax call.
The ajax request isnt that necessary, most wanted to know about the parameters.
function sendRequest($el, url, trackingUrl, actionTypeString) {
$.ajax({
method: 'POST',
url: url,
actionTrackingUrl: trackingUrl,
actionType: actionTypeString,
el: $el,
})
}
function testCase1() {
// ......... code
this.sendRequest($someEl, url, someTrackingUrl, someActionTypeString)
}
function testCase2() {
// .......code
this.sendRequest($someEl, someUrl, someActionTypeString);
}
Where in testCase2 I want to fill the 4th parameter (actionTypeString) and not 3rd parameter?
For testCase2, you would need to pass in a null parameter.
this.sendRequest($someEl, someUrl, null, someActionTypeString);
If you want to have optional parameters, the commonly-used pattern in javascript is to pass in one object containing all of the parameters, named appropriately:
function sendRequest(options) {
$.ajax({
method: 'POST',
url: options.url,
actionTrackingUrl: options.trackingUrl,
actionType: options.actionType,
el: options.$el,
})
}
function testCase1() {
// ......... code
this.sendRequest( {
$el: $someEl,
url: someUrl,
trackingUrl: someTrackingUrl,
actionType: someActionTypeString
});
}
function testCase2() {
// ......... code
this.sendRequest( {
$el: $someEl,
url: someUrl,
actionType: someActionTypeString
});
}
Parameters are assigned to named arguments in order. If you want to pass the 4th but not the 3rd argument, you need to explicitly pass null.
function testCase2() {
sendRequest($someEl, someUrl, null, someActionTypeString);
}
Additionally, I don't believe you are using this correctly - in this case it refers to the global object. You can just reference the function name.

Using Deferred in React.js or callback in my success function [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I have a React/ Flux app I am trying to return my "promiseSuccessData" but it has to be done outside of the ajax promise. Within the getChallengeData().
getChallengeData : function() {
$.ajax({
type: 'GET',
url: baseUrl + '1.0/challenge/result/' + challengeId,
crossDomain: true,
xhrFields : {
withCredentials : true
},
})
.done(function(promiseSuccessData) {
_challenges = promiseSuccessData;
})
.fail(function(jqXhr) {
console.log(jqXhr)
console.log('failed to register');
});
//This is where I want to "return _challenges" but _challenges isn't available here
},
You should return the promise instead, and add the done handler outside where you need to use the value (I will assume that getChallengeData is a method of an object called myObj for the sake of the example):
getChallengeData : function() {
return $.ajax({
type: 'GET',
url: baseUrl + '1.0/challenge/result/' + challengeId,
crossDomain: true,
xhrFields : {
withCredentials : true
},
}).fail(function(jqXhr) {
console.log(jqXhr)
console.log('failed to register');
});
},
And then, when you use it:
myObj.getChallengeData().done(function(promiseSuccessData) {
_challenges = promiseSuccessData;
//do something with challenges.
});
Edit: Saw that the OP wanted to return the value of _challenges, not just work with it somehow.
You can't work with _challenges until the done function has run. When working with asynchronous Promises, you'll want to return the actual Promise (jQuery Deferred?) and have the caller attach his own handler.
function foo() {
obj.getChallengeData()
.done(function(challenges) {
// Work with challenges here
});
}
var obj = {
getChallengeData : function() {
return $.ajax({
type: 'GET',
url: baseUrl + '1.0/challenge/result/' + challengeId,
crossDomain: true,
xhrFields : {
withCredentials : true
},
})
.fail(function(jqXhr) {
console.log(jqXhr)
console.log('failed to register');
});
},
// Other props
}

Saving result of ajax request in class variable [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
I want to build a javascript class which I initialize and will make only one ajax request to save some data off so I can do stuff with it aftewards. It is important that there is only one request for performance reasons.
Here is the initialisation
var web = new webService();
web.connect(app.info);
web.info();
and this is my class
function webService() {
this.d = new Object;
this.connect = function(app) {
console.log(app);
$.ajax({
url: 'my working url which gives me my jsonp object',
dataType: 'jsonp',
jsonp: 'jsoncallback',
timeout: 5000,
success: function(data) {
this.d = data;
},
async: false
});
}
this.info = function() {
console.log(this.d);
}
}
I was wondering if there might be a problem with synchronizing? I'm not sure so I wanted to ask you guys.
jQuery $.ajax (and similar methods, like $.getJSON()) will return a Deferred object. Like other JavaScript objects, this is a "thing" which you can store in a variable and pass around in your code. Then you can add (async) callbacks to it at any time:
// Don't include a 'success' callback yet.
$def = $.ajax(...);
// $def is an object which you can store globally
// or pass as an argument into other functions.
//
// Somewhere else, add a success callback:
$def.done(function(data) {
// ...
});
See http://api.jquery.com/category/deferred-object/
If you refactor your code to return a deferred object thus:
function webService() {
this.d = new Object;
this.connect = function(app) {
console.log(app);
return $.ajax({
url: 'my working url which gives me my jsonp object',
dataType: 'jsonp',
jsonp: 'jsoncallback',
timeout: 5000,
success: function(data) {
this.d = data;
}
});
}
this.info = function() {
console.log(this.d);
}
}
You can then use done:
var web = new webService();
web.connect(app.info).done(function() {web.info();});
this also means your A jax is asynchronous, like it should be.
You could argue if your going down this route though, what is your function webservice even doing. Why not just let deferred do all the work?
this.connect = function(app) {
console.log(app);
var that = this; //store this into a variable
$.ajax({
url: 'my working url which gives me my jsonp object',
dataType: 'jsonp',
jsonp: 'jsoncallback',
timeout: 5000,
success: function(data) {
that.d = data; //use that so you have the right scope
},
async: false
});
}
other option is to use bind or jQuery's proxy

Categories

Resources