create function with array index - javascript

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

Related

Not able to call method under success of api using .bind(this)

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.

How to sequence a recursive callback in Javascript?

I need to execute 3 ajax requests. I know that they happen to be asynchronous by default (And making them synchronous messes up the VM, so I don't want to go that way.) The way I do it is by calling a function three times passing variables.
result = '';
parse(var1);
parse(var2);
parse(var3);
view();
function parse(variable) {
//ajax request here
$.ajax({
type: 'POST',
url: 'script.php',
data: {variable: variable},
success: function (data) {
//result stored in a global variable
result += data;
}
});
}
function view() {
//do something with result
}
But right now, the view() is triggered right away when the result isn't done cooking. How do I set them up to happen one after the other? I read about callbacks but they are very confusing since I don't have 3 distinct functions but just one taking different variables.
You could store your variables in an array and use a function to make your ajax call:
var variables = [var1, var2, var3];
function callParse() {
if(variables.length) {
var currentVar = variables.shift();
parse(currentVar);
}
else {
view();
}
}
function parse(variable){
//ajax request here
$.ajax({
type:"POST",
url:'script.php',
data:{variable:variable},
success:function(data)
{
result+=data;
callParse();
}
});
}
function view(){
//do something with result
}
Try chained promises - from: https://css-tricks.com/multiple-simultaneous-ajax-requests-one-callback-jquery/
$.when(
// Get the HTML
$.get("/feature/", function(html) {
globalStore.html = html;
}),
// Get the CSS
$.get("/assets/feature.css", function(css) {
globalStore.css = css;
}),
// Get the JS
$.getScript("/assets/feature.js")
).then(function() {
// All is ready now, so...
// Add CSS to page
$("<style />").html(globalStore.css).appendTo("head");
// Add HTML to page
$("body").append(globalStore.html);
});
You could try doing it this way:
parseAndView([var1, var2, var3]);
function parseAndView(vars, index) {
index = index || 0; //initialize index if not passed
//execute the AJAX call only if there are more variables to parse
if (index < vars.length)
//ajax request here
$.ajax({
type: "POST",
url: 'script.php',
data: {variable: vars[index]},
success: function (data) {
// result stored in a global variable
result += data;
// recursive call to parse another variable
parseAndView(vars, index++);
}
});
else
view();
}
function view() {
//do something with result
}

How to pull JSON data from two different sources?

I was wondering if there is a way to pull and use JSON data from two different sources. Currently, the code looks like this:
//JSON1
$.getJSON('url1',function(data){
$.each(data,function(key,val){
//code
});
});
//JSON2
$.getJSON('url2',function(data){
$.each(data,function(key,val){
//code
});
});
When I do this, i seems that variables created from one JSON function aren't available in the other one, which makes it hard for them to be useful together.
Is there a better way to have these two work together?
This function takes an array of urls and a callback as parameters:
function getMultiJSON(urlList,callback) {
var respList = {};
var doneCount = 0;
for(var x = 0; x < urlList.length; x++) {
(function(url){
$.getJSON(url,function(data){
respList[url] = data;
doneCount++;
if(doneCount === urlList.length) {
callback(respList);
}
});
})(urlList[x]);
}
}
You would use it like this:
getMultiJSON(['url1','url2'],function(response) {
// in this case response would have 2 properties,
//
// response.url1 data for url1
// response.url2 data for url2
// continue logic here
});
You might want to add a timeout as the function will never call your handler should any of the URLs fail to load
Variable declared within the functions using var (or blocks, using let) are not available outside of the functions (or blocks).
$.getJSON('url1',function(data){
$.each(data,function(key,val){
var only_accessible_here = key;
});
});
So if you want variables that are accessible outside the scope of the function they are declared in, you need to declare them outside of the function they are used in.
var combined_stuff = ''
$.getJSON('url1',function(data){
$.each(data,function(key,val){
combined_stuff += val;
});
});
//JSON2
$.getJSON('url2',function(data){
$.each(data,function(key,val){
combined_stuff += val;
});
});
As Marc B says, there is no way to know which order the combined_stuff variable will be updated, either by JSON1 first, or by JSON2 first, or by only one, if one of the getJSON calls fail, or by neither if both fail.
If the order of updating is important, call the one you want to use second in the function of the one you want to call first.
var combined_stuff = ''
$.getJSON('url1',function(data){
$.each(data,function(key,val){
combined_stuff += val;
//JSON2
$.getJSON('url2',function(data){
$.each(data,function(key,val){
combined_stuff += val;
});
});
});
});
Easily using the open source project jinqJs (http://www.jinqJs.com)
var data1 = jinqJs().from('http://....').select();
var data2 = jinqJs().from('http://....').select();
var result = jinqJs().from(data1, data2).select();
The example does a sync call, you can do an async call by doing something like this:
var data1 = null;
jinqJs().from('http://....', function(self){ data1 = self.select(); });
Result will contain both results combined.
If you control the endpoint, you could make it return all of the data you want in one shot. Then your data would look like:
{
"url1_data": url1_json_data,
"url2_data": url2_json_data
}
If you still have 2 endpoints you need to hit, you can pass the result of your first ajax call to the second function (but this makes your 2 ajax calls synchronous):
function getJson1(){
$.getJSON('url1',function(data){
getJson2(data);
});
}
function getJson2(json1Data){
$.getJSON('url2',function(data){
//Do stuff with json1 and json2 data
});
}
getJson1();
I would recommend you to use $.when function available in jquery to execute both the methods in parallel and then take the action. See the code snipped below,
var json1 = [], json2 = [];
$.when(GetJson1(), GetJson2()).always(function () {
//this code will execute only after getjson1 and getjson2 methods are run executed
if (json1.length > 0)
{
$.each(json1,function(key,val){
//code
});
}
if (json2.length > 0)
{
$.each(json2,function(key,val){
//code
});
}
});
function GetJson1()
{
return $.ajax({
url: 'url1',
type: 'GET',
dataType: 'json',
success: function (data, textStatus, xhr) {
if (data != null) {
json1 = data;
}
},
error: function (xhr, textStatus, errorThrown) {
json1 = [];//just initialize to avoid js error
}
}
function GetJson2()
{
return $.ajax({
url: 'url2',
type: 'GET',
dataType: 'json',
success: function (data, textStatus, xhr) {
if (data != null) {
json2 = data;
}
},
error: function (xhr, textStatus, errorThrown) {
json2 = [];//just initialize to avoid js error
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
The returned data from each AJAX call are not available outside its own callback function. I'm sure there are more elegant (complex?) solutions, but a couple of simple, Occamic, solutions include global variables, or storing the received data in hidden input elements.
Within each callback function, just loop until the data from the other call is present:
function getJson1(){
$.getJSON('url1',function(data){
var d2 = '';
$('#hidden1').val(data);
while ( d2 == '' ){
//you should use a time delay here
d2 = $('#hidden2').val();
}
getJson2();
});
}
function getJson2(){
$.getJSON('url2',function(d2){
var d1 = '';
$('#hidden2').val(d2);
while ( d1 == '' ){
//you should use a time delay here
d1 = $('#hidden1').val();
}
//Do stuff with json1 and json2 data
});
}
getJson1();

jQuery AJAX issue? Or JS OOP scope issue?

I am trying to create a database handler class in javascript. I would like to call the class by simply using:
var databaseHandler = new DatabaseHandler();
result = databaseHandler.getResult("SELECT * FROM login");
I have created the class and used a callback for the ajax function (so as to wait for the ajax result to be returned). But all I am still receiving "undefined" as my result. If I use console.log(a) inside of the onComplete function, I get an array of the intended results.
(function(window){
//Database class
function DatabaseHandler(){
//Query
this.query = function(query, whenDone){
request = $.ajax({
url: "../optiMizeDashboards/php/DatabaseQuery.php",
type: "POST",
data: {query : query},
dataType: "JSON"
});
request.done(function(output) {
whenDone(output);
});
request.fail(function(jqXHR, textStatus) {
console.log(textStatus);
});
};
//Get result
this.getResult = function(query){
this.query(query, this.onComplete);
};
//Ajax callback
this.onComplete = function(a){
return a;
};
}
//Make available to global scope
window.DatabaseHandler = DatabaseHandler;
}(window))
My question is: Is this something to do with the variable scope, or the way that ajax works? I have read all the answers explaining that ajax is ASYNC and I thought I had handled that by using a callback function "onComplete"
Any help on this topic would be greatly appreciated!
You will not be able to return result immediately from calling getResult because underlying jQuery POST request is Asynchronous, instead you need to be passing a callback function which eventually will receive a result from server.
something like that:
(function(window){
//Database class
function DatabaseHandler(){
//Query
this.query = function(query, whenDone){
request = $.ajax({
url: "../optiMizeDashboards/php/DatabaseQuery.php",
type: "POST",
data: {query : query},
dataType: "JSON"
});
request.done(function(output) {
whenDone(output);
});
request.fail(function(jqXHR, textStatus) {
console.log(textStatus);
});
};
//Get result
this.getResult = function(query, callback){
this.query(query, callback);
};
}
//Make available to global scope
window.DatabaseHandler = DatabaseHandler;
}(window))
// then use it like so
var databaseHandler = new DatabaseHandler();
result = databaseHandler.getResult("SELECT * FROM login", function(data) {
//do something with data
});
PS: exposing direct SQL access to the databse on the client is very dangerous though, and I would not recommend doing that

Passing data from variables in JavaScript

I have created a small JavaScript application with the following function that calls a function to retrieve JSON data:
var months = function getMonths(){
$.getJSON("app/data/Cars/12Months", function (some_data) {
if (some_data == null) {
return false;
}
var months_data = new Array();
var value_data = new Array();
$.each(some_data, function(index, value) {
months_data.push(index);
value_data.push(value);
});
return[months_data,value_data];
});
}
I have then created, in the same file, another function that does something when a specific page is loaded. In this function the variable 'months' is passed to the variable 'result'.
$(document).on('pageshow', '#chartCar', function(){
$(document).ready(function() {
var result = months;
var date = result[0];
var values = result[1];
//more code here...
});
}
the problem is that, based on the debugger, the getMonths() function works fine and produces the expected output, but the 'result' variable in the second function can't obtain the values passed to it by the variable 'months'. Do you know how to solve this issue?
The problem is that you $.getJSON() function is asynchronous, so your data gets loaded later then you read it. There're two workarounds:
1. Replace your $.getJSON with $.ajax and setting async: false;
2. Put your code in $.getJSON callback:
var months = function getMonths(){
$.getJSON("app/data/Cars/12Months", function (some_data) {
if (some_data == null) {
return false;
}
var months_data = new Array();
var value_data = new Array();
$.each(some_data, function(index, value) {
months_data.push(index);
value_data.push(value);
});
var date = months_data;
var values = value_data;
//more code here..
})
}
There must be a syntax error.
replace
});
}
With
});
});
$.getJSON() is a wrapper around $.ajax which is async by default. But you treat it like a sync call.
You can use $.ajaxSetup()
$.ajaxSetup( { "async": false } );
$.getJSON(...)
$.ajaxSetup( { "async": true } );
or use $.ajax with async: false
$.ajax({
type: 'GET',
url: 'app/data/Cars/12Months',
dataType: 'json',
async: false,
success: function(some_data) {
//your code goes here
}
});
or if possible change the behavior of your app so that you process your data in a callback function.

Categories