sync call in tableau javascript - javascript

I am trying to do sync call using tableau.
var checkLen = $s_filter_i.length;
for (i = 0; i < checkLen; i++) {
var filterValfscr = $s_filter_i[i].VALUE;
Send_Tablo(filterValfscr);
}
When call this function Send_Tablo(filterValfscr) it runs the below code.
But the problem is before I get response form getSummaryDataAsync() it comes out of the function recalls Send_Tablo(filterValfscr) again I get the latest request data instead of first data request.
function Send_Tablo() {
var filter_indx = JSON.parse(window.localStorage.getItem('filter_indx'));
var arry = [];
for (var i = 0; i < filter_indx.s_filter_i.length; i++) {
Attr_lab_name = filter_indx.s_filter_i[i].ATTRIBUTELABEL;
arry.push(filter_indx.s_filter_i[i].VALUE);
}
currentViz.getWorkbook().changeParameterValueAsync('Attribute_Label', filterValfscr, Attr_lab_name, arry);
alert(filterValfscr);
var fScr_data;
sheet = currentViz.getWorkbook().getActiveSheet();
sheet.getSummaryDataAsync(options).then(function (t) {
data = t.getData();
console.log("Data", data);
frscr_demo();
});
function frscr_demo() {
//var fScr_data;
currentViz.getWorkbook().getActiveSheet().applyFilterAsync(Attr_lab_name, arry, tableau.FilterUpdateType.REPLACE);
sheet = currentViz.getWorkbook().getActiveSheet();
sheet.getSummaryDataAsync(options).then(function (t) {
fScr_data = t.getData();
console.log("FSCR", fScr_data);
var aa = $(fScr_data).length;
});
}
}
What I am try to achieve is Send_Tablo() should run all the Async function first before running the second iteration of Send_Tablo() from the for loop.
Do let me known what I am doing wrong? Thanks in advance.

Related

Concat in a for loop google app scripts javascript

I'm trying to filter in an array by data in another array using concat in a for loop. The elements of the following code are logging correctly, but the final array is logging an empty array.
function Shipments (){
var app = SpreadsheetApp;
var movementSS = app.getActiveSpreadsheet();
var infoSheet = movementSS.getSheetByName("Update Info");
var orderInfoSheet = movementSS.getSheetByName("Order Info");
var targetSheet = movementSS.getSheetByName("Shipments");
var ShipLogSS = app.openByUrl(URL).getSheetByName("Shipping Details");
var ShipArr = ShipLogSS.getRange(3,1,ShipLogSS.getLastRow(),ShipLogSS.getLastColumn()).getValues().
filter(function(item){if(item[1]!=""){return true}}).
map(function(r){return [r[0],r[1],r[2],r[4],r[10],r[11],r[16],r[18],r[23]]});
var supplierData = orderInfoSheet.getRange(3,6,orderInfoSheet.getLastRow(),1).getValues().
filter(function(item){if(item[0]!=""){return true}});
var supplierList = [];
for (var i in supplierData) {
var row = supplierData[i];
var duplicate = false;
for (var j in supplierList) {
if (row.join() == supplierList[j].join()) {
duplicate = true;
}
}
if (!duplicate) {
supplierList.push(row);
}
}
var supplierFilter = [];
for(var i = 0; i < supplierList.length; i++){
var shipments = ShipArr.filter(function(item){if(item[4]===supplierList[i][0]){return true}});
supplierFilter.concat(shipments);
}
Logger.log(supplierFilter);
}
Any help would be greatly appreciated!
You need to assign the result of concat onto the supplierFilter in order to see the changes in later iterations and in the outer scope.
You can also return the comparison done inside the .filter callback immediately, instead of an if statement - it looks a bit cleaner.
var supplierFilter = [];
for (var i = 0; i < supplierList.length; i++) {
var shipments = ShipArr.filter(function (item) { return item[4] === supplierList[i][0]; });
supplierFilter = supplierFilter.concat(shipments);
}
Logger.log(supplierFilter);

Callback is undefined and other stories

I got the following script, which is not working propperly. I know about getJSON's async nature, so I tried to build a callback function (jsonConsoleLog), which is supposed to be executed before getJSON get asigned to var (myJson = json;). After running debug in Chrome, I got two things out: A) debug is highlighting jsonConsoleLogcalls inside getJSON function as undefined.
B) Console is throwing TypeError: Cannot read property '0' of null for var friends = myJSON[0].friends;, which means the whole function doesn't work.
I'm in battle with it since saturday and I really don't know what to do. There's clearly something up with my callback function, but shoot me if I know what. Help?
var myJSON = null;
var main = document.getElementsByClassName('main');
var sec = document.getElementsByClassName('sec');
function getJSON(jsonConsoleLog){
$.getJSON('http://www.json-generator.com/api/json/get/cpldILZRfm? indent=2', function(json){
if (json != null){
console.log('Load Successfull!');
};
if (jsonConsoleLog){
jsonConsoleLog(json[0].friends);
}
myJSON = json;
});
};
function jsonConsoleLog(json) {
for (var i = 0; i < json.length; i++) {
console.log('friend: ' + friends[i]);
};
};
getJSON();
var friends = myJSON[0].friends;
function myFn1(){
for(var i = 0; i < friends.length; i++) {
main[i].innerHTML = friends[i].id;
};
};
function myFn2(){
for(var i = 0; i < friends.length; i++) {
main_div[i].innerHTML = friends[i].name;
};
};
main.innerHTML = myFn1();
sec.innerHTML = myFn2();
The first problem is because your function getJSON is expecting one formal argument, which you've called jsonConsoleLog. But you are not passing any arguments to getJSON. This means that inside getJSON the formal parameter, jsonConsoleLog, will indeed be undefined. Note that because you've named the formal parameter jsonConsoleLog, which is the same name as the function you're hoping to call, inside getJSON you won't have access to the function. What you need to do is pass the function as the parameter:
getJSON(jsonConsoleLog);
The second problem is I think to do with the json variable - it doesn't have a property 0 (i.e. the error is occurring when you try to treat it as an array and access element 0), which suggets that json is coming back empty, or is not an array.
you're calling getJSON without the callback parameter - therefore, the local variable jsonConsoleLog is undefined in getJSON
snip ...
function blah(json) { // changed name to avoid confusion in the answer - you can keep the name you had
for (var i = 0; i < json.length; i++) {
console.log('friend: ' + friends[i]);
};
};
getJSON(blah); // change made here (used the function name blah as changed above
var friends = myJSON[0].friends;
function myFn1(){
for(var i = 0; i < friends.length; i++) {
main[i].innerHTML = friends[i].id;
};
};
snip...
The issue with
var friends = myJSON[0].friends;
is duplicated here many many times ... $.getJSON is asynchronous and you are trying to use it synchronously
i.e. when you assign var friends = myJSON[0].friends; myJson hasn't been assigned in $.getjson ... in fact, $.getjson hasn't even BEGUN to run
here's all your code reorganised and rewritten to hopefully work
var main = document.getElementsByClassName('main');
var sec = document.getElementsByClassName('sec');
function getJSON(callback) {
$.getJSON('http://www.json-generator.com/api/json/get/cpldILZRfm? indent=2', function(json) {
if (json != null) {
console.log('Load Successfull!');
};
if (callback) {
callback(json);
}
});
};
function doThings(json) {
var friends = json[0].friends;
for (var i = 0; i < friends.length; i++) {
console.log('friend: ' + friends[i]);
};
function myFn1() {
for (var i = 0; i < friends.length; i++) {
main[i].innerHTML = friends[i].id;
};
};
function myFn2() {
for (var i = 0; i < friends.length; i++) {
main_div[i].innerHTML = friends[i].name;
};
};
main.innerHTML = myFn1();
sec.innerHTML = myFn2();
}
getJSON(doThings);
Correct, fully working code (basically the same as accepted, correct answer but stylistycally bit different)
var main = document.getElementsByClassName('main');
var sec = document.getElementsByClassName('sec');
var friends = null;
function getJSON(jsonConsoleLog){
$.getJSON('http://www.json-generator.com/api/json/get/cpldILZRfm?indent=2', function(json){
if (json != null){
console.log('Load Successfull!');
};
if (jsonConsoleLog){
jsonConsoleLog(json[0].friends);
}
});
};
function jsonConsoleLog(json) {
for (var i = 0; i < json.length; i++) {
console.log('friend: ' + json[i]);
};
friends = json;
myFn1();
myFn2();
};
function myFn1(){
for(var i = 0; i < friends.length; i++) {
main[i].innerHTML = friends[i].id;
};
};
function myFn2(){
for(var i = 0; i < friends.length; i++) {
main[i].innerHTML += friends[i].name;
};
};
getJSON(jsonConsoleLog);

Can't stop ajax call by clicking cancel button

I have a jQuery script. The concept is, when I am clicking a button, it's first calling an AJAX function to count the no. of rows from a particular query. Then on successful call it stores the number of rows in a jQuery variable.
Then it calls an AJAX function which runs repeatedly to call data from server with 10 rows per time, during this process there is a progress bar which increases or fills gradually each time some data is fetched from the db. when a chunk of data is received, its getting pushed in a global array. When the last ajax call returns blank no. or rows, then the process terminates.
Besides there is a button along with the progress loader, which when will be clicked, will terminate the AJAX process to stop the call and display the data received till now in a data-table.
Here's my script
<script type="text/javascript">
var oTable;
var outer_start_row = 0;
var outer_limit = 1;
var final_data = [];
var cancel = false;
var total_data = 0;
$(document).ready(function() {
window.prettyPrint() && prettyPrint();
$('#load').click(function()
{
var v = $('#drp_v').val();
var cnt = $('#drp_cnt').val();
var ctg = $('#drp_ctg').val();
var api = $('#drp_api').val();
var nt = $('#drp_nt').val();
alert("version :"+v+" category :"+ctg+" country :"+cnt);
$.post("ajax.php",
{
'version':v,'category':ctg,
'country':cnt,'network_id':nt,
'api':api,'func':'total_data'
},
function(data)
{
total_data = data;
$("#progress_bar_container").fadeIn('fast');
});
load_data_in_datatable();
});
});
function stop_it()
{
cancel == true;
}
function load_data_in_datatable()
{
if(cancel == true)
{
alert(cancel);
return;
}
else
{
var v = $('#drp_v').val();
var cnt = $('#drp_cnt').val();
var ctg = $('#drp_ctg').val();
var api = $('#drp_api').val();
var nt = $('#drp_nt').val();
$.post("ajax.php",
{
'version':v,'category':ctg,
'country':cnt,'network_id':nt,
'api':api,'func':'show_datatable',
'start_row':outer_start_row,'limit':outer_limit
},
function(response)
{
var data = response.data;
var limits = response.limits;
outer_limit = limits.limit;
outer_start_row = limits.start_row;
if(data.length > 0)
{
for(var i = 0; i < data.length; i++)
{
final_data.push(data[i]);
}
var current = parseInt(final_data.length);
percent_load = Math.round((current/parseInt(total_data))*100);
$(".progress-bar").css("width",percent_load+"%");
$(".progress-bar").text(percent_load+"%");
load_data_in_datatable();
}
else
{
create_datatable();
cancel = true;
return;
}
},'json');
}
}
function create_datatable()
{
$("#progress_bar_container").fadeOut('fast');
var aColumns = [];
var columns = [];
for(var i = 0; i < final_data.length; i++)
{
if(i>0)
break;
keycolumns = Object.keys(final_data[i]);
for(j = 0; j < keycolumns.length; j++)
{
if($.inArray(keycolumns[j],aColumns.sTitle)<=0)
{
aColumns.push({sTitle: keycolumns[j]}) //Checks if
columns.push(keycolumns[j]) //Checks if
}
}
}
var oTable = $('#jsontable').dataTable({
"columns":aColumns,
"sDom": 'T<"clear">lfrtip',
"oTableTools": {
"aButtons": [
{
"sExtends": "csv",
"sButtonText": "CSV",
}
]
}
});
oTable.fnClearTable();
var row = []
for(var i = 0; i < final_data.length; i++)
{
for(var c = 0; c < columns.length; c++)
{
row.push( final_data[i][columns[c]] ) ;
}
oTable.fnAddData(row);
row = [];
}
}
</script>
The problem, is that I can't stop the AJAX when clicking on the cancel button.
function stop_it() {
cancel == true;
}
This function seems to be wrong, you need to assign true to the cancel variable but you have mistakenly written comparison operator(equal to/==) instead it should be:
function stop_it() {
cancel = true;
}
I think you are calling this function while stopping AJAX in between the process.
check link describe how you abort(stop/cancle) ajax request.
Jquery allows you to stop ajax request with .abort() method.
Aborting an AJAX request

nested javascript queries in parse

I have the code below. Basically I have 3 nested parse queries. One is getting a number of "followers" and for each follower I am getting a number of "ideas" and for each idea I would like to get that idea creator's name (a user in the user table).
The first two nested queries work but then when i try to get the name of the user (the creator of the idea), that last nested query DOES NOT execute in order. That query is skipped, and then it is executed later in the code. Why is this happening please?
var iMax = 20;
var jMax = 10;
var IdeaList = new Array();
var IdeaListCounter = 0;
var myuser = Parse.User.current();
var Followers = new Parse.Query("Followers");
Followers.equalTo("Source_User",{__type: "Pointer",className: "_User",objectId: myuser.id});
Followers.find({
success: function(results) {
for (var i = 0; i < results.length; i++) {
var object = results[i];
var Ideas = new Parse.Query("Ideas");
Ideas.equalTo("objectId_User", {__type: "Pointer",className: "_User",objectId: object.get('Destination_User').id});
Ideas.find({
success: function(results2) {
for (i=0;i<iMax;i++) {
IdeaList[i]=new Array();
for (j=0;j<jMax;j++) {
IdeaList[i][j]=0;
}
}
for (var j = 0; j < results2.length; j++) {
var object2 = results2[j];
var ideausername2 = "";
IdeaListCounter++;
var ideausername = new Parse.Query("User");
ideausername.equalTo("objectId",object2.get('objectId_User').id);
ideausername.first({
success: function(ideausernameresult) {
ideausername2 = ideausernameresult.get("name");
}
});
IdeaList[IdeaListCounter,0] = object2.get('objectId_User').id + " " + ideausername2; //sourceuser
IdeaList[IdeaListCounter,1] = object2.get('IdeaText'); //text
IdeaList[IdeaListCounter,2] = object2.get('IdeaImage'); //image
IdeaList[IdeaListCounter,3] = object2.get('IdeaLikes'); //likes
IdeaList[IdeaListCounter,4] = object2.get('IdeaReport'); //reports
Your nested query is asynchronous.
Check out the answer at the following for guidance:
Nested queries using javascript in cloud code (Parse.com)

Why does the second loop execute before the first loop?

so this might be a repost, but I don't really know how to explain my second problem.
I have this code:
var paragraphsArray = new Array();
function setParagraphs(offSet)
{
offSet = offSet * 12;
for (var i = 1; i < 13; i++)
{
var parX = i + offSet;
var testASd = $.get('php/entryParagraphs.php', {idd: parX}).done(function(paragraph)
{
//clear paragraph1 div
document.getElementById("paragraph1").innerHTML = "";
//create p elements
var pElem = document.createElement("p");
pElem.setAttribute("id", "pEntry"+i);
document.getElementById("paragraph1").appendChild(pElem);
$("pEntry"+i).text(paragraph);
});
}
}
edited: I removed the second loop because it was unnecessary, for some reason the p element creation starts on i==13, which is the extra one that shouldn't even do.
for some reason the second loop executes first, so the paragraphArray is printed out as undefined. I managed to "fix" the order with the setTimeout() function, BUT I still get the undefined message, instead of the value. In the first loop the value is printed out fine, but if I try and put it in a $("p").text(paragraph); I also get undefined. So although I was right about the execution order, the problem is still there!
Because first is in ajax call, declare paragraphsArray in global space and use a callback function, try this:
*Updated
var paragraphsArray = [];
function setParagraphs(offSet) {
offSet = offSet * 12;
var request = 0;
for (var i = 1; i < 13; i++) {
var parX = i + offSet;
var testASd = $.get('php/entryParagraphs.php', {idd: parX}).done(function(paragraph) {
request++;
paragraphsArray[request] = paragraph;
console.log(paragraphsArray[request]);
if (request === 12) {
alert('first');
callback();
}
});
}
}
function callback() {
for (var i = 1; i < 13; i++) {
console.log(paragraphsArray[i]);
}
alert('second');
}
Run the second loop inside of the first loop.
function setParagraphs (offSet) {
//paragraphs
var testing = 0;
var paragraphsArray = new Array();
offSet = offSet * 12;
for (var i=1;i<13;i++) {
var parX = i + offSet;
var testASd = $.get('php/entryParagraphs.php', { idd: parX }).done(function(paragraph) {
paragraphsArray[i] = paragraph;
console.log(paragraphsArray[i]);
alert('first');
for (var i=1;i<13;i++) {
console.log(paragraphsArray[i]);
alert('second');
}
});
}
}
$.get is async function. 1st cycle will just send requests and wouldn't wait for response, so 2nd cycle will start right after first, without getting response of $.get function. Thats why console.log(paragraphsArray[i]); in 2nd cycle shows undefined.
You only can handle response in first cylce.
You can use $("p").text(paragraph); only like in this example:
var testASd = $.get('php/entryParagraphs.php', { idd: parX }).done(function(paragraph) {
paragraphsArray[i] = paragraph;
console.log(paragraphsArray[i]);
alert('first');
$("p").text(paragraph);
});
You can't use variables, which are assigned in function
function(paragraph) {
paragraphsArray[i] = paragraph;
console.log(paragraphsArray[i]);
alert('first');
$("p").text(paragraph);
}
outside of this function.
To achieve what you want you have to use another approach.
HTML will be:
<div id='paragraphs'>
</div>
JS code:
var testASd = $.get('php/entryParagraphs.php', { idd: parX }).done(function(paragraph) {
$("#results").append("<p>"+paragraph+"</p>")
});
You should use ~ this code. I just show you approach.

Categories