create 2d arrays with Rollbase API and store in client-side

Posted by gwf on 20-May-2015 09:27

I want to create 2d arrays with the Rollbase API and store them in client-side variables. How do I do this?

This is what I tried but it just returns undefined:

var clientArray;

function myCallback(values) {
 clientArray = values;
}

rbf_selectQuery("SELECT field1#value,COUNT(field1#value) FROM object1 GROUP BY field1#value", 1000, myCallback);

alert(clientArray);

Thank you,

Greg

Posted by Santosh Patel on 07-Jul-2015 21:44

Apologies for coming back so late. This is what happens when you mark a lot of stuff as TODO. Hope this still helps you.

<div id="div1"> 

<script> 
function renderChart(labels, values) {
	// variables for chart 
	var canvasWidth = 600; 
	var canvasHeight = 400; 
	var pieXCoordinate = 150; 
	var pieYCoordinate = 200; 
	var pieRadius = 100; 
	// create canvas 
	var rIndustry = Raphael(document.getElementById("div1"), canvasWidth, canvasHeight); 
	// create pie chart 
	var pieIndustry = rIndustry.piechart(pieXCoordinate, pieYCoordinate, pieRadius, values, { legend: labels, legendpos: "east" }); 
}

$(document).on('chartDataAvailable', function(e, labels, values) {
	renderChart(labels, values);
});

rbf_selectQuery("select R281410#value, sum(Stock_Value) from stock1 group by R281410#value", 1000, function(values) { 
	// parse your data into 2 1D arrays	
	var industryLabels = ["Manufacturing","Financial Services","IT"]; 
	// and one for values: 
	var industryValues = [43,20,18]; 
	
	$(document).trigger('chartDataAvailable', [ industryLabels, industryValues ]); 
});

</script>


All Replies

Posted by pvorobie on 20-May-2015 11:25

Please place all data processing code into your callback function, not just after API call. AJAX is asynchronous process.

Posted by gwf on 20-May-2015 11:52

I'm sorry I don't understand -- can you demonstrate by rewriting my code above?

Thank you,

Greg

Posted by Orchid Corpin on 20-May-2015 13:26

Hi,

This is how to get the 2d array values, need to add a loop which in my sample is a for loop, see code below

function myCallback(values) {
	for(x=0; x<values.length; x++) {
		//[x][0] represent your 1st parameter in the query
		//[x][1] represent your 2nd parameter in the query and so on..
		alert(values[x][0] +"---"+ +values[x][1]);
	}
	
} 
rbf_selectQuery("SELECT field1#value,COUNT(field1#value) FROM object1 GROUP BY field1#value", 1000, myCallback);

Hope this may help.

Regards,

Orchid

Posted by Orchid Corpin on 20-May-2015 13:50

UPDATE: Storing 2d array to variable

var clientArray = [];
function myCallback(values) {
	for(x=0; x<values.length; x++) {
		//[x][0] represent your 1st parameter in the query
		//[x][1] represent your 2nd parameter in the query and so on..
		clientArray[x] = values[x][0] +"---"+ +values[x][1];
	}
	alert(clientArray);
} 
rbf_selectQuery("SELECT field1#value,COUNT(field1#value) FROM object1 GROUP BY field1#value", 1000, myCallback);

Regards,
Orchid

Posted by gwf on 20-May-2015 16:23

Thank you, Orchid. So I think to get the array into the variable is as straightforward as

var clientArray = [];

function myCallback(values) {

   clientArray = values;

   }

   alert(clientArray);

}

rbf_selectQuery("SELECT field1#value,COUNT(field1#value) FROM object1 GROUP BY field1#value", 1000, myCallback);

But if the alert statement comes outside of the callback function (or if I try to use the clientArray variable in any way outside of the function) it doesn't work. I want to store the array in the client-side variable so I can use it in the UI, so I need to access the variable outside of the callback function.

Is there a way to do this with rbf_selectQuery? Or should it be done with an EVAL block and rbv_api.selectQuery? If so, what would that code look like?

Thank you,

Greg

Posted by jquerijero on 20-May-2015 17:21

Even if you declare clientArray as global (outside any function), the call to rbf_selectQuery is async. Your myCallback function which sets the clientArray is not guaranteed to run first before the alert statement.

Posted by gwf on 20-May-2015 18:15

So how do I store an array from the Rollbase database in a client-side variable?

Posted by gwf on 21-May-2015 09:59

p.s. if I put the AJAX calls and callback functions to store them in variables in a js file linked in the portal header or footer, will those calls run before the page content is loaded so that I can use the client-side array variables in pages? Or is there another way to force all of the calls to run before page content is loaded?

Posted by pvorobie on 21-May-2015 11:22

It is not about assigning variable, it is about when you will use it. Immediately after AJAX call result is undefined, as you have observed.

Posted by gwf on 21-May-2015 11:39

So how do I store an array from the Rollbase database in a client-side variable?

Posted by Orchid Corpin on 22-May-2015 15:19

Your code is correct, sorry mine is a long method. And yes selectQuery is async, you may consider having timeout to your alert.

var clientArray; function myCallback(values) { 
	clientArray = values; 
} 
rbf_selectQuery("SELECT field1#value,COUNT(field1#value) FROM object1 GROUP BY field1#value", 1000, myCallback);

setTimeout("alert(clientArray);", 1000);

Regards,

Orchid

Posted by Santosh Patel on 25-May-2015 01:11

setTimeout is never a good idea. Network lag to server slowdown, anything can affect the time taken by the selectQuery to respond back with data. The code assumes that clientArray will contain values after 1sec.

A possible solution would be to write code based on custom events. Look here for a Javascript only way and here for a jQuery specific solution. I'd prefer the  jQuery solution as Rollbase incorporates jQuery libraries.

function whatIWantToDoWithValuesInUI(queryResults) {
    ...
}

function selectQueryCallback(values) {
    // Trigger a custom event
    $.event.trigger('selectQueryEvent', { result: values });
}

// Register to listen to the custom event
$(document).bind('selectQueryEvent', function(e) {
    // e.result will have values here
    // e.anything will have anything passed in the event object above
    whatIWantToDoWithValuesInUI(e.result);
});

rbf_selectQuery("SELECT field1#value,COUNT(field1#value) FROM object1 GROUP BY field1#value", 1000, selectQueryCallback);


Posted by gwf on 26-May-2015 09:23

Thank you, Santosh.

Since it seems that what I am trying to do is a bit uncommon, I want to make sure I am taking the right approach: my goal is to build custom charts in the portal for a CRM-like application using a client-side javascript charting library. For example, a pie chart will show the breakdown of opportunities by industry. What I thought made sense was to run the selectQuery to get the 2d matrix of something like

Manufacturing            43

Financial Services    20

IT                                  18

... and so on, then pass that array to a client-side variable which can be used to generate the chart. That's where this question comes up as to how to use the results of the async AJAX call outside of the callback function. I want to set all of these variables in one place, like a JS file in the portal footer, to be able to manage them more effectively. I think the other option of wrapping all the individual charts in the script components on multiple portal pages in separate callback functions will get too cumbersome.

So does this approach make sense or is there a better way to do this?

Thank you,

Greg

Posted by pvorobie on 26-May-2015 11:03

I would recommend you to consider server-side APIs to prepare HTML on server side. This should work unless you wish to process user's input dynamically.

Server-side APIs are synchronous (unlike AJAX), so you could use results in familiar way.

Posted by gwf on 26-May-2015 16:02

Thank you.

When I use the server-side API with this code:

<script>

var clientArray= "#EVAL[rbv_api.selectQuery('SELECT field1#value,COUNT(field1#value) FROM object1 GROUP BY field1#value', 1000)]";
  
alert(clientArray);

</script>

I get this alert:  "org.mozilla.javascript.NativeJavaArray@67a4e0d1".

Can I pass a 2d array from the server-side API to a client-side variable?

Posted by Santosh Patel on 26-May-2015 16:06

"..and so on, then pass that array to a client-side variable which can be used to generate the chart. That's where this question comes up as to how to use the results of the async AJAX call outside of the callback function"

The custom events can help you with precisely that. Along with the event you can pass arbitrary data that listeners can get when the event is fired.

What charting library are you using? And share a sample chart generation code assuming the results are available. I'll see if I can get a working example for you using selectQuery.

Posted by pvorobie on 26-May-2015 16:55

But you're on the right track. Just add code (inside EVAL block) to extract values you need.

Posted by tanagorns@progress.in.th on 27-May-2015 05:12

Hi!!

I think you can use server-side API it trued because Client -side API is AJAX concept . it work to 1 round trip ,1 request and 1 response . so you can use server-side api by Eval blog for get value to variable and if use want to display array for monitor. you can use "JSON.stringify(data)" .

I hope to help you.

Regards

BOY

Posted by gwf on 27-May-2015 11:18

Thank you very much, Santosh. I am using g.Raphael (http://g.raphaeljs.com/). Code for a simple chart following the example of a breakdown of opportunities by industry is as follows:

<div id="div1">

<script>
      
// ...at this point in the code the client-side 2d array is already parsed into two 1d arrays, one for labels:

var industryLabels = ["Manufacturing","Financial Services","IT"];
    
// and one for values:

var industryValues = [43,20,18];

// variables for chart
  
var canvasWidth = 600;
var canvasHeight = 400;
var pieXCoordinate = 150;
var pieYCoordinate = 200;
var pieRadius = 100;

// create canvas

var rIndustry = Raphael(document.getElementById("div1"), canvasWidth, canvasHeight);

// create pie chart

var pieIndustry = rIndustry.piechart(pieXCoordinate, pieYCoordinate, pieRadius, industryValues, { legend: industryLabels, legendpos: "east" });

</script>


If you can show me the code for the custom event to create the client-side Javascript 2d array that would be awesome -- thank you!

Posted by gwf on 27-May-2015 11:21

Thank you, BOY. When I try JSON.stringify it just turns the value of org.mozilla.javascript.NativeJavaArray@67a4e0d1 into a string "org.mozilla.javascript.NativeJavaArray@67a4e0d1", it does not create an array. Am I missing something?

Posted by Santosh Patel on 07-Jul-2015 21:44

Apologies for coming back so late. This is what happens when you mark a lot of stuff as TODO. Hope this still helps you.

<div id="div1"> 

<script> 
function renderChart(labels, values) {
	// variables for chart 
	var canvasWidth = 600; 
	var canvasHeight = 400; 
	var pieXCoordinate = 150; 
	var pieYCoordinate = 200; 
	var pieRadius = 100; 
	// create canvas 
	var rIndustry = Raphael(document.getElementById("div1"), canvasWidth, canvasHeight); 
	// create pie chart 
	var pieIndustry = rIndustry.piechart(pieXCoordinate, pieYCoordinate, pieRadius, values, { legend: labels, legendpos: "east" }); 
}

$(document).on('chartDataAvailable', function(e, labels, values) {
	renderChart(labels, values);
});

rbf_selectQuery("select R281410#value, sum(Stock_Value) from stock1 group by R281410#value", 1000, function(values) { 
	// parse your data into 2 1D arrays	
	var industryLabels = ["Manufacturing","Financial Services","IT"]; 
	// and one for values: 
	var industryValues = [43,20,18]; 
	
	$(document).trigger('chartDataAvailable', [ industryLabels, industryValues ]); 
});

</script>


Posted by gwf on 29-Jul-2015 09:43

Awesome, thank you so much, Santosh!!

Greg

This thread is closed