I am trying to call method on success of my ajax api call. I have stored this(context) inside local variable that but still not able to get context of that view and getting error that.setPdfUrl is not a function. And important thing is i am calling method by pub/sub mechanism.
My code looks like -
kf.Events.off('getPdfUrl');
kf.Events.on('getPdfUrl', this.getPdfUrl);
getPdfUrl: function() {
var that = this;
$.ajax({
url: kf.Settings.fileGeneratorUrl() + "/ikfc/singlereport",
type: 'POST',
data: {
//content
},
success: function(result) {
that.setPdfUrl(kf.Settings.fileGeneratorUrl() + '/download?guid=' +
result.Message);
}
});
}.bind(this),
setPdfUrl: function(url){
this.pdfUrl = url;
}
Getting
Uncaught TypeError: that.setPdfUrl is not a function
I got solution by binding context at initialize -
kf.Events.on('getPdfUrl', this.getPdfUrl.bind(this))
You can just move following lines.
getPdfUrl: function() {
var that = this;
Change to
var that = this;
getPdfUrl: function() {
it will work, there are multiple ways to achieve this. but for now, you can use this.
Related
I have to create lot of functions that contain almost same pattern and coding.
Creating multiple function becomes more useful to use different purpose and pages for my project. For example:
function cls(){
$.ajax({
url:"crud/fetch.php",
method:"POST",
data:{cat:'cls'},
success:function(data){
$('#cls').html(data);
}
});
}
function stdt(){
$.ajax({
url:"crud/fetch.php",
method:"POST",
data:{cat:'stdt'},
success:function(data){
$('#stdt').html(data);
}
});
}
function sec(){
......
//same pattern
}
function pdl(){
......
//same pattern
}
I tried to contain these function in one function to reduce code that seems clean, easy for debugging and re-editing.
So I tried storing all desired function name in one array and create function using each index.
But I am getting Uncaught TypeError: cls is not a function. I have tried without using window[cat]. I think it is foolish way, but tried, hoping it can works. Please suggest how can I assign or create function using each array index value.
var menu = ["cls", "stdt", "sec", "pdl", "sub", "xsub", "cls_sub", "cls_xsub", "xam", "mrksch", "grdsch", "sclnfo"];
$.each(menu, function(i,cat){
var ftch = window[cat];
function ftch(){
$.ajax({
url:"crud/fetch.php",
method:"POST",
data:{menu:cat},
success:function(data){
$('#"' + cat+ '"';).html(data);
}
});
}
})
You can use anonymous functions. Also, quick side note, you have a syntax error with $('#"' + cat+ '"';):
var menu = ["cls", "stdt", "sec", "pdl", "sub", "xsub", "cls_sub", "cls_xsub", "xam", "mrksch", "grdsch", "sclnfo"];
$.each(menu, function(i,cat){
window[cat] = function () {
$.ajax({
url:"crud/fetch.php",
method:"POST",
data:{menu:cat},
success:function(data){
$('#' + cat).html(data);
}
});
}
});
Although, I would highly recommend that you create a custom variable/class, to avoid too much pollution to the global scope:
window.fetch = {};
var menu = ["cls", "stdt", "sec", "pdl", "sub", "xsub", "cls_sub", "cls_xsub", "xam", "mrksch", "grdsch", "sclnfo"];
$.each(menu, function(i,cat){
window.fetch[cat] = function () {
$.ajax({
url:"crud/fetch.php",
method:"POST",
data:{menu:cat},
success:function(data){
$('#"' + cat+ '"';).html(data);
}
});
}
});
You can even make the above approach dynamic with a Proxy (This is just a demonstration, you should simply just create a function with a parameter):
var fetchMenu = new Proxy({}, {
get: function(obj, cat, val) {
return () => {
console.log('Lets load ' + cat);
};
}
});
var menu = ["cls", "stdt", "sec", "pdl", "sub", "xsub", "cls_sub", "cls_xsub", "xam", "mrksch", "grdsch", "sclnfo"];
fetchMenu.cls();
Although, this appears to be an X/Y issue. What's your reasoning for doing this? Why not just create a function that takes a parameter for what to fetch?
function fetchCat(cat) {
$.ajax({
url:"crud/fetch.php",
method:"POST",
data:{menu:cat},
success:function(data){
$('#' + cat).html(data);
}
});
}
Later on...you can do something as simple as:
$.each(menu, (i, cat) => fetchCat(cat));
You are trying to call a string in this code
var ftch = window[cat];
function ftch(){
I'm guessing you think this means create a function called cat on the window object, which you are then defining with ftch, however this simply gets the object stored at window[cat] (which will be undefined) and then tries to create another function called ftch.
To fix this, simply change your code to:
window[cat] = function(){
$.ajax({
url:"crud/fetch.php",
method:"POST",
data:{menu:cat},
success:function(data){
$('#"' + cat+ '"';).html(data);
}
});
}
Try calling the function using the window command
window(function_name,parameters);
I'm trying to pass a parameter from a onload GET method call to a POST method. The GET method is being loaded on window.onload and the POST function is not in the onload call otherwise the POST function will trigger once the window has loaded. I only want to trigger POST function when I click a button.
How can I pass a variable from a onload AJAX call to my POST function?
The only way I could think of is using a global variable however I don't think that's a good way of passing it to another function.
window.onload = function () {
function firstCallBack() {
$.get('http://website.com/API/docs/v1').then(function(data1){
var passThis = "PassMeToPOST"
}).then(function (data2) {
})
}
}
POST function
function saveSettings(passThatVar) {
var urlVal = window.__env.url+ "Preview/TypeDefinition";
var xslSettingVal = $('#PreviewXml').val().replace(/\n/g, "");
var allData = {
'ObjectName': passThatVar,
'DisplayDefinition': setting,
}
$.ajax({
url: urlVal,
type: "POST",
data: JSON.stringify(allData),
success: function (data) {
console.log('success');
}
});
}
Button HTML:
<button onclick="saveSetting()"> Save Setting </button>
Try this:
Your button:
<button id="save-settings"> Save Setting </button>
After your get request, set a data-attribute to your button:
function firstCallBack() {
$.get('http://website.com/API/docs/v1').then(function(data1){
$("#save-settings").data("passMe", "PassMeToPOST");
}).then(function (data2) {
})
}
Bind the click event(its a best practice than using inline events):
$("#save-settings").on("click", saveSetting);
On your saveSetting() function:
function saveSetting() {
var allData = {
'ObjectName': $(this).data("passMe"),
'DisplayDefinition': setting,
}
//... your post request
}
You can also check if the get request has finished before starting the post request(to avoid a bug in an extreme scenario):
if (!$(this).data("passMe")) {
return;
}
You're basically asking how to keep a variable out of the global scope. This is called encapsulation. It is a good instinct but a large topic. Here is a post that I like on the topic: http://javascriptissexy.com/oop-in-javascript-what-you-need-to-know/
One low budget way of doing this is instead of making a global variable for your value, make a global namespace for your own use.
var MyUniquelyNamedThing = {};
...
// get response:
MyUniquelyNamedThing.ThatValueINeed = data;
...
// posting:
data = { val1: MyUniquelyNamedThing.ThatValueINeed , etc. };
I'm making a jquery library to use an application with the json rpc protocol but I'm stuck with a little problem.
This is the fiddle that shows the code (obviously it can't work): https://jsfiddle.net/L9qkkxLe/3/.
;(function($) {
$.lib = function(options) {
var outputHTML = [],
plugin = this;
var APIcall = function(api_method, api_params) {
request = {};
request.id = Math.floor((Math.random() * 100) + 1);
request.jsonrpc = '2.0';
request.method = api_method;
request.params = (api_params) ? api_params : [];
$.ajax({
type: "POST",
url: "http://localhost:8898/jsonrpc",
data: JSON.stringify(request),
timeout: 3000,
beforeSend: function(xhr) {
xhr.setRequestHeader('Authorization', window.btoa(options.username + ":" + options.password));
},
success: function(data) {
handleData(data, api_method);
},
error: function(jqXHR, textStatus, errorThrown) {
log("Connection time out: can't reach it. Try changing the settings.");
isConnected = "false";
},
dataType: "json"
});
}
var handleData = function(data, method) {
if (method == "getgenres") {
outputHTML = data.result.genres; //I need data.result.genres to return in getgenres function
}
}
var log = function(msg) {
if (options.debug == true) console.log(msg);
}
plugin.getgenres = function() {
APIcall("getgenres");
return outputHTML; //This is sadly empty.
}
};
}(jQuery));
var init = new $.lib();
console.log(init.getgenres());
I need that the getgenres function returns data.result.genres but actually it returns an empty array because getgenres is called for first and only after the handleData function gives to outputHTML the value that I need.
You are performing an asynchronous AJAX request, which means you can't actually get back the data immediately. There are two ways to solve your issue: making it synchronous (easy but ill advised) or using a callback (a little bit more complex but generally accepted):
In your getgenres function, you could accept one more parameter: callback
plugin.getgenres = function(callback) {
/* Dont forget APIcall already took two parameters in, so callback has to be the third in line! */
APIcall("getgenres", false, callback);
}
Now modify your APIcall function to accept your callback:
var APIcall = function(api_method, api_params, callback) { ... }
And call the callback from the successful completion call - instead of having a handler method in between wrapped in a function, you can simply pass the anonymous function. So instead of success: function(data){ handle(data); }, just use:
success: callback
The anonymous function that we will pass to it will receive as its first parameter the data you were passing to the handler. Now you can do the following:
var myGenres = [];
var init = new $.lib();
init.getgenres(function(data){
/* Now your data is actually loaded and available here. */
myGenres = data;
console.log(myGenres);
});
I would like to point out that there are many better ways to handle this, including turning this into a Constructor (More here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain) instead of the strange amalgamation of functions and variables you have now, as well as using JS Promises (here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) to make this easier. But the basic gist should be here.
Update (potential implementation)
Because I mentioned that this could be done in a way that I think is clearer to read and use. I do not know all use cases for this, but from the provided example I would change the code to something looking like the following. Please also note I am not an expert on jQuery plugins, so I am avoiding plugging into jQuery and just using it as an easy AJAX call.
function getAjax(){
if(!window.jQuery || !window.$) throw("jQuery is required for this plugin to function.");
this.data = [];
this.request = '';
return this;
}
getAjax.prototype = {
createRequest : function(method, parameters){
this.request = {};
this.request.id = Math.floor((Math.random() * 100) + 1);
this.request.jsonrpc = '2.0';
this.request.method = method;
this.request.params = parameters || [];
return this;
},
callRequest : function(options, callback, error){
var self = this;
// We could also `throw` here as you need to set up a request before calling it.
if(!this.request) return this;
else {
$.ajax({
// We will allow passing a type and url using the options and use sensible defaults.
type: options.type || "POST",
url: options.url || "http://localhost:8898/jsonrpc",
// Here we use the request we made earlier.
data: JSON.stringify(this.request),
timeout: options.timeout || 3000,
beforeSend: function(xhr){
xhr.setRequestHeader(
'Authorization',
window.btoa( options.username + ":" + options.password)
);
},
// We will also store all the made request in this object. That could be useful later, but it's not necessary. After that, we call the callback.
success: function(data){
var store = {request:self.request, data: data};
self.data.push(store);
// Call the callback and bind `this` to it so we can use `this` to access potentially pther data. Also, pass the results as arguments.
callback(data, self.request.id).bind(self);
},
// Error function!
error: error,
dataType: options.dataType || "json"
});
}
return this;
}
}
// Example use
new getAjax().createRequest('getgenres').callRequest({
username: 'myusername',
password: 'mypassword'
}, function(data, id){
// Success! Do with your data what you want.
console.log(data);
}, function(e){
// Error!
alert('An error has occurred: ' + e.statusText);
console.log(e);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
What I do in those occasions is this:
You are supplying a method. So put a reference to the a callback function. In this case plugin.getGenresFinalize. When handleData is called it will fire that callBack function. This way you can pass multiple methods to the api call for different types of data.
plugin.getgenres = function() {
APIcall(this.getgenresFinalize);
}
plugin.getgenresFinalize = function(data) {
console.log(data);
}
var handleData = function(data, method) {
method(data);
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
$(this) inside of AJAX success not working
I have the following sample code (JSFiddle to follow)
AdvancedSearch = function() {
this.current = 'test';
}
AdvancedSearch.prototype.InitPage = function() {
var t = this.current;
this.PrePopulate()
}
AdvancedSearch.prototype.UpdateData= function() {
alert(this.current);
}
AdvancedSearch.prototype.PrePopulate = function() {
this.UpdateData();
$.ajax({
url: 'http://fiddle.jshell.net/',
success: function(msg) {
this.UpdateData();
}
});
}
var as = new AdvancedSearch();
as.InitPage();
I have the 'http://fiddle.jshell.net' in there so prevent the Access-Control-Allow-Origin error on their site.
When executing this code, I get the following error:
Uncaught TypeError: Object # has not method 'UpdateData'
If you execute the JSFiddle, you will find that when PrePopulate is called, it runs the this.UpdateData() at the beginning of the function just fine. But as soon as the Ajax call is finished, you get the error.
Any thoughts to why this is happening? Perhaps I'm approaching this in the wrong way. Any insight would help.
Here is my JSFiddle: http://jsfiddle.net/B4NRY/2/
The callback you give to $.ajax isn't called with your instance of AdvancedSearch as context (this).
Solution 1 (valid for all the similar callback problems ) :
AdvancedSearch.prototype.PrePopulate = function() {
this.UpdateData();
var that = this; // register the that variable in the closure of the callback
$.ajax({
url: 'http://fiddle.jshell.net/',
success: function(msg) {
that.UpdateData();
}
});
}
Solution 2 (specific to $.ajax but very clean, thanks Felix) :
AdvancedSearch.prototype.PrePopulate = function() {
this.UpdateData();
$.ajax({
url: 'http://fiddle.jshell.net/',
context: this,
success: function(msg) {
this.UpdateData();
}
});
}
I have an issue with a method ive created for an object ive created. one of the methods requires a callback to another method. the problem is i cant add the data to the object that called the method. it keeps coming back as undefined. otherwise when i send the data to the console it is correct. how can i get the data back to the method?
var blogObject = new Object();
var following = [...];
//get posts from those blogs
blogObject.getPosts = function () {
var followersBlogArray = new Array();
for (var i = 0; i < this.following.length;i++){
var followersBlog = new Object();
// get construct blog url
var complete_blog_url = ...;
i call the getAvatar function here sending the current user on the following array with it.
followersBlog.avatar = blogObject.getAvatar(this.following[i]);
that part goes smoothly
followersBlogArray.push(followersBlog);
}
this.followersBlogArray = followersBlogArray;
}
here is the function that gets called with the current user in following array
this function calls an ajax function
blogObject.getAvatar = function (data) {
console.log("get avatar");
var url = "..."
this ajax function does its work and has a callback function of showAvatar
$(function() {
$.ajax({
type: "GET",
dataType: "jsonp",
cache: false,
url: url,
data: {
jsonp:"blogObject.showAvatar"
}
});
});
}
this function gets called no problem when getAvatar is called. i cant however get it to add the data to the followersBlog object.
blogObject.showAvatar = function (avatar) {
return avatar
}
everything in here works fine but i cant get the showAvatar function to add to my followersBlog object. ive tried
blogObject.showAvatar = function (avatar) {
this.followersBlog.avatar = avatar;
return avatar
}
that didnt work of course. it shows up as undefined. can anyone help?
so somethings like...
$(function() {
$.ajax({
type: "GET",
dataType: "jsonp",
cache: false,
url: url,
complete: function () {
this.avatar = data;
}
data: {
jsonp:"blogObject.showAvatar"
}
});
});
}
Welcome to the world of asynchronous programming.
You need to account for the fact that $.ajax() will not return a value immediately, and Javascript engines will not wait for it to complete before moving on to the next line of code.
To fix this, you'll need to refactor your code and provide a callback for your AJAX call, which will call the code that you want to execute upon receiving a response from $.ajax(). This callback should be passed in as the complete argument for $.ajax().
The correct option for setting the JSONP callback is jsonpCallback. The recommendation from the API for .ajax(...) is to set it as a function.
{
// ...
jsonpCallback: function (returnedData) {
blogObject.showAvatar(returnedData);
},
// ...
}