getObjectCount from several related tables at once

My users table has 8 related tables for which i would like to get the object count for each for use in my app.
For single table this should be

String whereClause = "Users["RELATED TABLE NAME]" +
 ".objectId='" + user.getObjectId() + "'";



 DataQueryBuilder queryBuilder = DataQueryBuilder.create();
 queryBuilder.setWhereClause(whereClause);



 Backendless.Data.of(OtherRelationship.class).getObjectCount(queryBuilder, new AsyncCallback<Integer>() {
 @Override
 public void handleResponse(Integer relatedTableObjectCount) {
 
 }



 @Override
 public void handleFault(BackendlessFault fault) {



 }
 });

Rather than make 8 of the above calls, is there as better way to implement this?

I need to sum up data for 4 of the tables together, and sum up data for other 4 together.

Regards,
George

Hi Odhiambo,

You might implement your kind of ‘count’ (on 4 tables) as a custom business logic event, so that from your app it will be just one request, and on the server-side you’ll have the same 4 calls to sum the counts.

Sergey, could you please provide a link to an example or documentation? I can’t seem to find how it’s done.

Regards,
George

George,

here’s a quick start guide on API Services: https://backendless.com/docs/bl-js/doc.html#bl_basic_quick_start_guide_js

Regards,
Mark

Mark, thanks for the quick start, i have gone through the CUSTOM EVENTS section, just a few clarifications

1.When creating the custom event handler in Console, do i select Language Java or JS, am developing in Java so i guess the former but only JS generates custom event handler code to edit and deploy, Java doesn’t.

  1. For my use case, getting the object count on 4 tables and summing them up, how will i structure my code? Put 4 of the above getObjectCount code, one for each Table inside the below block?
Backendless.ServerCode.customEvent('sumOfObjectCounts', function(req) {
  //add your code here
getObjectCount (for Table1)
getObjectCount (for Table2)
getObjectCount (for Table3)
getObjectCount (for Table4)
});

What does the API for dispatching custom events below do exactly?

Backendless.Events.dispatch( "foo", args, new AsyncCallback <Map>()
{

Am confused between

Backendless.ServerCode.customEvent() {} 

and

Backendless.Events.dispatch(){}

Does one sit in the console, and the other in the client side, or are both implemented from the client side.

Am assuming the return value of each object count will return an integer value, not sure how to sum these up in console before sending the value back to the client.

Regards,
George

Hi George,

Please see below:

===============================
When creating the custom event handler in Console, do i select Language Java or JS, am developing in Java so i guess the former but only JS generates custom event handler code to edit and deploy, Java doesn’t.

You can use either Java or JavaScript, whichever you feel more comfortable. The code is generated for both, however, you can edit the code and then deploy inside of console only for JS. For Java, you need to download generated code, edit/compile/deploy from your own computer. You can download the code using the Download menu located on the same screen.

For my use case, getting the object count on 4 tables and summing them up, how will i structure my code? Put 4 of the above getObjectCount code, one for each Table inside the below block?

Backendless.ServerCode.customEvent('sumOfObjectCounts', function(req) {
//add your code here
getObjectCount (for Table1)
getObjectCount (for Table2)
getObjectCount (for Table3)
getObjectCount (for Table4)
});

Your custom event should return objects counts for the specified tables. The return type of a custom event is an object. See the doc here:
https://backendless.com/docs/bl-js/doc.html#bl_custom_events

I suppose the returned object may look like this:
{
“table1”: objectCountForTable1,

“table2”: objectCountForTable2,

“table3”: objectCountForTable3,

“table4”: objectCountForTable4
}

where objectCountForTable1, objectCountForTable2, objectCountForTable3, objectCountForTable4 are values obtained with the API. Keep in mind that when you use Backendless API inside the business logic, the calls must be non-blocking, so you should use promises to get the return values and then assemble the final object.

What does the API for dispatching custom events below do exactly?

Backendless.Events.dispatch( "foo", args, new AsyncCallback <Map>()
{

Am confused between

Backendless.ServerCode.customEvent() {}

and

Backendless.Events.dispatch(){}

“Backendless.ServerCode.customEvent” is used to declare your custom event on the server side. “Backendless.Events.dispatch” is used to invoke the custom event from the client application.

Hope this helps.

Mark

Thanks Mark, am getting closer:)

Is it correct to declare a custom event this way? Or is it an overkill?

@BackendlessEvent("RelatedTablesObjectCount")
public class RelatedTablesObjectCountEventHandler extends CustomEventHandler{
 @Override
 public Map handleEvent(RunnerContext context, Map eventArgs) {
// code for getting object count for Table1
DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause("Users[Table1]" +
".objectId='" + user.getObjectId() + "'");
Backendless.Data.of(Table1.class).getObjectCount(queryBuilder, new AsyncCallback<Integer>() {
@Override
public void handleResponse(Integer table1ObjectCount) {
}
@Override
public void handleFault(BackendlessFault fault) {
}
});
// code for getting object count for Table2
DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause(Users[Table2]" +
".objectId='" + user.getObjectId() + "'");
Backendless.Data.of(Table2.class).getObjectCount(queryBuilder, new AsyncCallback<Integer>() {
@Override
public void handleResponse(Integer table2ObjectCount) {
}
@Override
public void handleFault(BackendlessFault fault) {
}
});
// code for getting object count for Table3
DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause("Users[Table3]" +
".objectId='" + user.getObjectId() + "'");
Backendless.Data.of(Table3.class).getObjectCount(queryBuilder, new AsyncCallback<Integer>() {
@Override
public void handleResponse(Integer table3ObjectCount) {
}
@Override
public void handleFault(BackendlessFault fault) {
}
});
// code for getting object count for Table4
DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause("Users[Table4]" +
".objectId='" + user.getObjectId() + "'");
Backendless.Data.of(Table4.class).getObjectCount(queryBuilder, new AsyncCallback<Integer>() {
@Override
public void handleResponse(Integer table4ObjectCount) {
}
@Override
public void handleFault(BackendlessFault fault) {
}
});
HashMap result = new HashMap();
result.put("table1", objectCountForTable1);
result.put("table2", objectCountForTable2);
result.put("table3", objectCountForTable3);
result.put("table4", objectCountForTable4);
 
return result;
 }
}

Is it ok to have

return result;

as the return value of the method

@Override
 public Map handleEvent(RunnerContext context, Map eventArgs) {
}

overridden within the RelatedTablesObjectCountEventHandler class other than

 return super.handleEvent(context, eventArgs);

which i get when i invoke Override Methods inside the class?

I am not sure what args i will put in

Backendless.Events.dispatch

as per the below guidelines

HashMap args = new HashMap();
args.put( "?", "?" );
 
Backendless.Events.dispatch( "RelatedTablesObjectCount", args, new AsyncCallback <Map>()
{
 @Override
 public void handleResponse( Map result )
 {
 System.out.println( "received result " + result );
 }
 
 @Override
 public void handleFault( BackendlessFault backendlessFault )
 {
 System.out.println( "got error " + backendlessFault.toString() );
 }
});

Please help once more,

Regards,
George

I am thinking i should supply the custom event handler with the User objectId since am using it in several places in the whereClauses, and in any case the custom event is unniversal for all users so it has no way of determining which user is calling the event

Mark, ignore the above, i have realized i ought to put server side code in there.