0

I have a simple jsonRpcService with a method that returns true or false.

I have a button with code at CCJS and SSJS events. I want to stop code execution if RPC is returning true, however, it looks code is triggered before addCallBack is finished and code at SSJS or is being executed

Is there any way to wait for addCallBack response before continuing with any other CCSJ instruction or SSJS code. I was expecting that return false will stop any code execution.

Here my code:

var lastupdate = '#{javascript:document1.getDocument().getLastModified().toString();}';
var myobject = rpcDocLock.checkUpdate(lastupdate);
myobject.addCallback(function(modified){
    alert(modified);  // #2
    if (modified){
        alert("This document has been modified.");  // #3
        return false;   
    }
});

alert("This alert is triggered and RPC has not finished its execution.") // #1

I added 3 alerts so you can see the order they are being executed.

PSolano
  • 398
  • 5
  • 21
  • Just move the code which should be executed after the call back in your *addCallBack* function. – Sven Hasselbach Feb 19 '13 at 15:27
  • I tried that @SvenHasselbach. I added an else statement within addCallback:`myobject.addCallback(function(modified){ alert(modified); // #2 if (modified){ alert("This document has been modified."); // #3 return false; }else{ validateForm(); } });` The problem is my button has code also on SSJS; so this is being triggered no matter what is the result of addCallback. What I want is to stop any code execution if RCP method is returning **true** – PSolano Feb 19 '13 at 15:48
  • So, if I'm reading this correctly, the client portion of your event triggers server code that determines whether the server portion of your event should run. Why not just move that logic to the server portion of the event, so all the server code runs from a single entry point? – Tim Tripcony Feb 20 '13 at 02:55

2 Answers2

1

You should never write blocking code in a webbrowser, because if you would the browser would appear hung. That's why you have the callback function, continue you code there if you need to retrieve something from the server.

You also have the onComplete event that can be trigged after a refresh is done.

===================================================== Edit

This is the two ways how I would solve the problem.

  1. Client side use the callback function move the SSJS code to a hidden button (With CSS) When your function code ends and you want the SSJS code to kick in. find the button by ID and to a click() on button thru javascriptList item
  2. Move everything to SSJS and if the document is modified return an error message to the user using a custom validator or in your code check for modified and add a value to a scope variable that is show in in a computed field.
Fredrik Norling
  • 3,461
  • 17
  • 21
  • Can you elaborate a bit more your answer? I'm returning something from server (true if document was modified and false if document has not being modified). I cannot use onComplete because I have code also on SSJS event, that is why I want to stop any code execution if addCallback is returning true. onComplete event will be triggered after code from CSJS and SSJS is executed. – PSolano Feb 19 '13 at 15:21
  • Thanks @Fredrik for suggestion; both are excellent ideas. However, I want to reuse this code in different actions or buttons at Client Side level that is why I was trying to use the RPC control. – PSolano Feb 20 '13 at 12:34
1

In your Button, add the following lines to get control about the Dojo XHR request:

if( ! dojo._xhr )
    dojo._xhr = dojo.xhr;

dojo.xhr = function ( args, ioArgs, addArgs ){
    ioArgs["sync"] = true;
    return dojo._xhr( args, ioArgs, addArgs );
}

This will force all calls to be sync (which blocks the browser, disables the timeout etc.). See here for more: dojo.xhrGet supported object properties

Now you can call your RPC call:

var myobject = rpcDocLock.checkUpdate(lastupdate);
myobject.addCallback(function(modified){

    // -=> RESET DOJO XHR CALL BACK FIRST!
    dojo.xhr = dojo._xhr;
    delete( dojo._xhr );

    // -=> DO THE OTHER STUFF
    alert(modified);  // #2
    if (modified){
        alert("This document has been modified.");  // #3
        return false;   
    }
});

I am not sure what exactly happens when the RPC call fails, but this may stop all CSJS (it's synced).

Sven Hasselbach
  • 10,455
  • 1
  • 18
  • 26
  • This is great @Sven RPC is now synced; however the return false is just exiting from addCallback and its executing code on SSJS. I had to assigned a variable result inside if statement and then check for its value after addCallback:`if (modified){ alert("This document has been modified."); // #2 result = false; return false; alert("This should not be displayed."); // #? }` Any ideas if how can stop code execution? – PSolano Feb 20 '13 at 12:30
  • Yes, in your button create a variable: *var ret = true;* Then change the variable value in your callback function if required (*ret=false*). The last line of code in your CSJS returns *ret*. – Sven Hasselbach Feb 20 '13 at 21:01