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

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);
},

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.

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

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();
})
}

pass a parameter to an ajax callback

I have a javascript function which must get a file and pass it with another parameter:
getJsonFile = function(fileName, callback, error, data) {
var ajaxOptions = {
url: util.pathJoin([Options.server_cache_path, jsonRelativeFileName]),
type: "GET",
dataType: "json",
success: function(album) {
callback(album, data)
},
error: error
};
The getJsonFile function is called many times in for cycles throughout the application.
However, in the callback function, I sometimes find that the value of data is altered... Why does it happen? What's the solution?
As you described above, you are calling getJsonFile function from a loop (for) and most likely passing the data parameter as reference. In that scenario, you are passing a pointer to a variable which is changing in every loop iteration and by the time the success callback is invoked, data parameter has a reference to a different object from the original call.
One way to fix this kind of problems is to make copies of the parameters you received (or at least from data) OR capture the value you are interested in using a closure to capture the current data referenced value.
getJsonFile = function(fileName, callback, error, data) {
var callbackCall = (function(myData) {
return function(myAlbum) { callback(myAlbum, myData); };
})(data);
var ajaxOptions = {
url: util.pathJoin([Options.server_cache_path, jsonRelativeFileName]),
type: "GET",
dataType: "json",
success: function(album) {
callbackCall(album);
},
error: error
};
Avoiding the callbackCall variable
getJsonFile = function(fileName, callback, error, data) {
// Code omitted...
success: (function(myData) {
return function(album) { callback(album, myData); };
})(data)
// Code omitted...
}

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.

what is 'this' refers to in jquery's $.ajax success?

Sorry if I have made some mistakes of js terms in my question.
I'm trying to call a method in $.ajax success event which is within the same namespace, here is the demo:
"use strict";
var example = window.example || {};
example.Demo = {
doSomething: function(data) {
console.log(data);
},
main: function() {
$(document).ready(function() {
$.ajax({
url: 'url/to/some/place',
type: 'GET',
async: true,
dataType: "json",
success: function (data) {
this.doSomething(data);
}
});
});
},
};
example.Demo.main()
but it will fail with the following error:
Object # has no method 'doSomething',
seems this can works:
...
main: function() {
var that = this;
...
...
success: function (data) {
that.doSomething(data);
...
but I want to know whether there is any best practice for such case, or this is exactly the proper solution.
it refers the ajax settings by default, you can use the context to pass a custom object
context
This object will be made the context of all Ajax-related callbacks. By
default, the context is an object that represents the ajax settings
used in the call ($.ajaxSettings merged with the settings passed to
$.ajax).
example.Demo = {
doSomething: function (data) {
console.log(data);
},
main: function () {
//don't use dom ready handler here
$.ajax({
url: 'url/to/some/place',
type: 'GET',
//see the use of context
context: this,
async: true,
dataType: "json",
success: function (data) {
this.doSomething(data);
}
});
},
};
In JavaScript this always refers to the “owner” of the function we're executing, or rather, to the object that a function is a method of. When we define our faithful function doSomething() in a page, its owner is the page, or rather, the window object (or global object) of JavaScript. An onclick property, though, is owned by the HTML element it belongs to.
This "ownership" is the result of JavaScript's object oriented approach. See the Objects as associative arrays page for some more information.
Remove $(document).ready(function(){... inside the main , that will solve the problem

Categories

Resources