Event Dispatch doesnt work from JS code

APP ID: EEB0D956-B06D-88EE-FFB5-F17A2C993A00

I followed the example at https://backendless.com/docs/bl-js/bl_custom_events.html and created the demo custom event handler ‘foo’.

calling it via the REST endpoint causes it to execute.
the javascript example code:

var eventArg = {weather:"sunny"};  

var successHandler = function( response ) {  
};  

var errorHandler = function( response ) {  
};  

Backendless.Events.dispatch( "foo", eventArgs )  
  .then( successHandler )  
  .catch( errorHandler );

doesnt cause the event handler to fire.
I double checked that the dispatch gets executed. It just has no effect. The event handler got modified to insert a row into a table. the row is only inserted when the event is triggered via a POST to

https://api.backendless.com///servercode/events/

Hi again, @Frederic_Schulz

Can you describe exactly what is not working for you? How do you call the method? If you call it via REST what behavior do you have? And what exactly is the code you call JS handler with?

Regards,
Marina

curl -X “POST” “https://api.backendless.com/EEB0D956-B06D-88EE-FFB5-F17A2C993A00/APIKEY/servercode/events/foo” -H ‘Content-Type: application/json’ -d ‘{}’ works fine as expected. as for the js code: i c&p’ed the code you saw in my fist post to one of my endpoints. the endpoint executes as expected when called but the event handler is never activated

@Frederic_Schulz Try to add third parameter async true

var eventArg = {weather:"sunny"};  
var successHandler = function( response ) {  
};  
var errorHandler = function( response ) {  
};  
Backendless.Events.dispatch( "foo", eventArgs, true )  
  .then( successHandler )  
  .catch( errorHandler );

well. that crashes the server:

16:09:52.729 Error: Backendless encountered an error while handling the request. An internal trouble ticket with ID 3AF081E8-CC80-FD4E-FF48-70E18119BD00 has been created and we will be investigating the issue.
ExecutionType for name 'true' wasn't found.
java.lang.IllegalArgumentException: ExecutionType for name 'true' wasn't found.
        at com.backendless.servercode.ExecutionType.getByNameIgnoreCase(ExecutionType.java:25)
        at java.base/java.util.Optional.map(Optional.java:265)
        at controllers.ServerCode.invokeEvent(ServerCode.java:87)
        at router.Routes$$anonfun$routes$1.$anonfun$applyOrElse$1315(Routes.scala:15265)
        at play.core.routing.HandlerInvokerFactory$$anon$8.resultCall(HandlerInvoker.scala:146)
        at play.core.routing.HandlerInvokerFactory$$anon$8.resultCall(HandlerInvoker.scala:145)
        at play.core.routing.HandlerInvokerFactory$JavaActionInvokerFactory$$anon$3$$anon$4$$anon$5.invocation(HandlerInvoker.scala:111)
        at play.core.j.JavaAction$$anon$1.call(JavaAction.scala:119)
        at play.http.DefaultActionCreator$1.call(DefaultActionCreator.java:33)
        at com.backendless.TimeOutAction.call(TimeOutAction.java:28)
        at com.backendless.old.security.SuperScalingAction.lambda$call$0(SuperScalingAction.java:26)
        at com.backendless.services.billing.superscaling.SuperScalingManager.applyWithPolicies(SuperScalingManager.java:49
[...]

i also found an error in the docs. There is a ‘s’ missing in the docs.
var eventArg = {weather:"sunny"}; should be var eventArgs = {weather:"sunny"};

Hello @Frederic_Schulz

you forget to return a promise or/and you do not use async/await before Backendless.Data.of("...").save(...)

and as result, the worker is exited before it sends a request for saving an object.

Backendless.ServerCode.customEvent('foo', async function(req) {
	const savedObject = await Backendless.Data.of("....").save({...});
...

Regards, Vlad

How is this related to my question/error statement?
I’m stating that calling the same eventhandler e.g. the foo one from the docs works via the example for REST but not javascript.

using the example in the docs doesnt work. even after correcting the typo.

edit: to clarify. the servercode works. i verified via the rest endpoint

why do you think the JS code is not working?
have you tried to apply this approach with async/await?

you can verify it by monitoring your logs in real-time

and how/where do you run your JS code?

yes i did. the current code in the eventhandler has a logger and a db insert.

/**
* @param {Object} req The request object contains information about the request
* @param {Object} req.context The execution context contains an information about application, current user and event
* @param {Object} req.args 
*
* @returns {Object|Promise.<Object>|void} The event caller will receive this value
*/
Backendless.ServerCode.customEvent('foo', async function(req) {
	await Backendless.Data.of("events_workaround").save({'name': 'from the eventhandler'});
		Backendless.Logging.setLogReportingPolicy(0, 0);
		var logger = Backendless.Logging.getLogger('HANDLER');
		logger.warn('akjsdhflkjsadhfkjsadhflkasdhfjkhsadfjkhasdkljfhsadjklfhsadjklhfksjadhfklasjhdfkljsadhfklsjadhfkjsadhflkjsadhfkjhsdkfjhasdklfjhsadkljfhsdakljfhaskdjhflkasdjhksadjlfhlaksdf')
  return { weather:"sunny" }
});

if i see both beeing executed I assume the handler to be called. this is only the case if I call it directly via REST

I just executed your code and it works properly.

But there is a typo in naming eventArg variable

while running the code you should see the error “ReferenceError: eventArgs is not defined”

Following that tutorial, I created this as my event in the Backendless Console.

Backendless.ServerCode.customEvent('foo', function(req) {
  return { weather:"sunny" }
});

I saved and deployed. Then in my JS I called it with this:

var successHandler = function( response ) {  
	console.log(response)
};  

var errorHandler = function( response ) {  
};  

Backendless.Events.dispatch("foo")  
.then( successHandler )  
.catch( errorHandler );

And that successfully retrieved the value for me

image

i mentioned that i the reply prior to your first post. its incorrect in the docs

Is this the typo you are referring to? Cause this will cause a JS error

image

This typo we will fix (BKNDLSS-22948)

just curious don’t you dispatch the event from the Business Logic (any API service, eventHandler or timer) because it won’t work in that way

The event is dispatched from within one of my REST service endpoints thats deployed to backendless business logic. Is that the problem? Am i supposed to use some other feature?

yes, that’s the problem.
you can not dispatch BusinessLogic events from BusinessLogic using the same JS-SDK instance, because of preventing any cyclical issues.

You have a few options how to get it working:

  1. send a plain request using Backendless.Request but using any APIKye except ServerCodeAPIKey

  2. move your logic into a separated function and run it from the eventHandler and from any other place for example APIService, see example

async function doSomething(){
 ....
}

Backendless.ServerCode.customEvent('foo', async function(req) {
 await doSomething()
  ...
})

class YourAPIService {
 async foobar(){
    await doSomething()
    ...
 }
}

Backendless.ServerCode.addService(YourAPIService);

I would recommend you to consider the second one

Regards, Vlad

Am i correct in my assumption that this behavior extends to a beforeCreate(‘tableA’) event not firing if it is server code that enters new data in tableA?

That fact that this just silently fails is very irritating and should at least generate a log entry or something.

If you have multiple services used by different clients or even if you use the bl console the persistence event handlers are an obvious place to put data integrity/mangling logic.

in the case of custom events as described above an error should be thrown. i havent seen this behavior documented anywhere and if control flow is altered/terminated that needs to be communicated.

Hi @Frederic_Schulz,

Your assumption is correct

About the rest, this behavior will be described in the documentation

Regards, Viktor