Backendless Support
 
Answered

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

  1. String whereClause = "Users["RELATED TABLE NAME]" +
  2. ".objectId='" + user.getObjectId() + "'";
  3. DataQueryBuilder queryBuilder = DataQueryBuilder.create();
  4. queryBuilder.setWhereClause(whereClause);
  5. Backendless.Data.of(OtherRelationship.class).getObjectCount(queryBuilder, new AsyncCallback<Integer>() {
  6. @Override
  7. public void handleResponse(Integer relatedTableObjectCount) {
  8. }
  9. @Override
  10. public void handleFault(BackendlessFault fault) {
  11. }
  12. });

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

Leave a Comment

Comments (8)

photo
1

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.

photo
1

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

Regards,

George

photo
1

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

photo
1

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.

2. 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?

  1. Backendless.ServerCode.customEvent('sumOfObjectCounts', function(req) {
  2. //add your code here
  3. getObjectCount (for Table1)
  4. getObjectCount (for Table2)
  5. getObjectCount (for Table3)
  6. getObjectCount (for Table4)
  7. });

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

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

Am confused between

  1. Backendless.ServerCode.customEvent() {}

and

  1. 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

photo
1

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?

  1. Backendless.ServerCode.customEvent('sumOfObjectCounts', function(req) {
  2. //add your code here
  3. getObjectCount (for Table1)
  4. getObjectCount (for Table2)
  5. getObjectCount (for Table3)
  6. getObjectCount (for Table4)
  7. });

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?

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

Am confused between

  1. Backendless.ServerCode.customEvent() {}

and

  1. 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

photo
1

Thanks Mark, am getting closer:)

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

  1. @BackendlessEvent("RelatedTablesObjectCount")
  2. public class RelatedTablesObjectCountEventHandler extends CustomEventHandler{
  3. @Override
  4. public Map handleEvent(RunnerContext context, Map eventArgs) {
  5. // code for getting object count for Table1
  6. DataQueryBuilder queryBuilder = DataQueryBuilder.create();
  7. queryBuilder.setWhereClause("Users[Table1]" +
  8. ".objectId='" + user.getObjectId() + "'");
  9. Backendless.Data.of(Table1.class).getObjectCount(queryBuilder, new AsyncCallback<Integer>() {
  10. @Override
  11. public void handleResponse(Integer table1ObjectCount) {
  12. }
  13. @Override
  14. public void handleFault(BackendlessFault fault) {
  15. }
  16. });
  17. // code for getting object count for Table2
  18. DataQueryBuilder queryBuilder = DataQueryBuilder.create();
  19. queryBuilder.setWhereClause(Users[Table2]" +
  20. ".objectId='" + user.getObjectId() + "'");
  21. Backendless.Data.of(Table2.class).getObjectCount(queryBuilder, new AsyncCallback<Integer>() {
  22. @Override
  23. public void handleResponse(Integer table2ObjectCount) {
  24. }
  25. @Override
  26. public void handleFault(BackendlessFault fault) {
  27. }
  28. });
  29. // code for getting object count for Table3
  30. DataQueryBuilder queryBuilder = DataQueryBuilder.create();
  31. queryBuilder.setWhereClause("Users[Table3]" +
  32. ".objectId='" + user.getObjectId() + "'");
  33. Backendless.Data.of(Table3.class).getObjectCount(queryBuilder, new AsyncCallback<Integer>() {
  34. @Override
  35. public void handleResponse(Integer table3ObjectCount) {
  36. }
  37. @Override
  38. public void handleFault(BackendlessFault fault) {
  39. }
  40. });
  41. // code for getting object count for Table4
  42. DataQueryBuilder queryBuilder = DataQueryBuilder.create();
  43. queryBuilder.setWhereClause("Users[Table4]" +
  44. ".objectId='" + user.getObjectId() + "'");
  45. Backendless.Data.of(Table4.class).getObjectCount(queryBuilder, new AsyncCallback<Integer>() {
  46. @Override
  47. public void handleResponse(Integer table4ObjectCount) {
  48. }
  49. @Override
  50. public void handleFault(BackendlessFault fault) {
  51. }
  52. });
  53. HashMap result = new HashMap();
  54. result.put("table1", objectCountForTable1);
  55. result.put("table2", objectCountForTable2);
  56. result.put("table3", objectCountForTable3);
  57. result.put("table4", objectCountForTable4);
  58. return result;
  59. }
  60. }

Is it ok to have

  1. return result;

as the return value of the method

  1. @Override
  2. public Map handleEvent(RunnerContext context, Map eventArgs) {
  3. }

overridden within the RelatedTablesObjectCountEventHandler class other than

  1. 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

  1. Backendless.Events.dispatch

as per the below guidelines

  1. HashMap args = new HashMap();
  2. args.put( "?", "?" );
  3. Backendless.Events.dispatch( "RelatedTablesObjectCount", args, new AsyncCallback <Map>()
  4. {
  5. @Override
  6. public void handleResponse( Map result )
  7. {
  8. System.out.println( "received result " + result );
  9. }
  10. @Override
  11. public void handleFault( BackendlessFault backendlessFault )
  12. {
  13. System.out.println( "got error " + backendlessFault.toString() );
  14. }
  15. });

Please help once more,

Regards,

George

photo
1

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

photo
1

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

photo