Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    RPCManager.sendRequest callback does not fire

    I have a string function for a button click event. It successfully makes an HTTP request to a Java servlet which returns a PDF file. The file is correct and is able to be saved. I need to be able to look at the response that came back, so I added a callback function. It does not seem to fire. The code is below. All of before the RPCManager.sendRequest already works and has not been changed.
    Code:
    Log.logDebug("****servlet version*** MeetingForm.CreateAgendaButton.Click");
    
    	var form = MeetingForm;
    	
    	var oldPrintOptions = form.getValue("AgendaPrintOptions"); 	Log.logDebug("*** old[Agenda]PrintOptions: " + oldPrintOptions);	
    	var vmOptions = meetingTypeVM.getValues().Agenda.Options; 
    	var vmNewOptions = vmOptions.Agenda.Options;	
    	var vmTopic = meetingTypeVM.getValues().Agenda.Topic;
    	var vmNewTopic = vmTopic.Agenda.Topic;
    	var vmIssue = meetingTypeVM.getValues().Agenda.Issue;
    	var vmNewIssue = vmIssue.Agenda.Issue;	
    	var vmTask = meetingTypeVM.getValues().Agenda.Task;
    	var vmNewTask = vmTask.Agenda.Task;	
    	var vmSpecial = meetingTypeVM.getValues().Agenda.Special;
    	var vmNewSpecial = vmSpecial.Agenda.Special;	
    	var vmNewPrintOptions = { Options: vmNewOptions, Topic: vmNewTopic, Issue: vmNewIssue, Task: vmNewTask, Special: vmNewSpecial  };
    	var newPrintOptions = isc.JSON.encode(vmNewPrintOptions);		
    	if (oldPrintOptions != newPrintOptions) { Log.logDebug("*** new[Agenda]PrintOptions: " + newPrintOptions);
    		form.changesPending = true;
    		form.setValue("AgendaPrintOptions", newPrintOptions);
    	}
    	
    //	isc.say("calling MeetingAgendaServlet11");
    
    	var meetingDate;
    	meetingDate = String(form.getValue("MeetingDate"));
    	if (meetingDate == "undefined") meetingDate = ""; 
    	var meetingTime;
    	meetingTime = String(form.getValue("MeetingTime"));
    	if (meetingTime == "undefined") meetingTime = ""; 
    	
    	var d = new Date();
    	var minOffset = d.getTimezoneOffset();
    	var s;
    	if (minOffset < 0) {
    		s = "+"; minOffset = -1 * minOffset;
    	} else {
    		s = "-";
    	}
    	var hrs = 100 + (minOffset / 60);
    	var mins = 100 + minOffset - ( (hrs - 100) * 60);
    	var timeZoneOffset = s + hrs.toString().substring(1) + ":" + mins.toString().substring(1);
    	
    	RPCManager.sendRequest({
    		httpMethod: "POST",
    		actionURL: "/servlet/MeetingAgendaServlet11",
    		params: {	meetingDate:		meetingDate,
    					meetingTime:		meetingTime,
    					timeZoneOffset:		timeZoneOffset,
    					meetingTypeID:		String(Application.currentMeetingTypeID),
    					agendaPrintOptions: String(form.getValue("AgendaPrintOptions"))
    			},
    		downloadResult: true, 
    		downloadToNewWindow:false,
    		useSimpleHttp: true,
    		callback: function(response) {
    			Log.logDebug("*** callback response: " + response);
    			isc.clearPrompt();
    			if (response.status == RPCResponce.STATUS_SUCCESS) {
    				if (!window.EmailForm) {
    					var message = "Component ID \"EmailForm\", target of action \"Edit Record\" does not exist";
    					isc.Log.logWarn(message);
    					if (isc.designTime) {
    						isc.say(message);
    					}
    				}
    				var headers = {};
    				headers = response.httpHeaders;
    				Log.logDebug("*** response headers: " + headers);
    				form = EmailForm;
    				form.clearValues();
    				form.setValue("toEmails", headers.toEmails ) ;
    				form.setValue("ccEmails", headers.ccEmails ) ;
    				form.setValue("bccEmails", headers.bccEmails ) ;
    				//form.getItem("CloseButton").setDisabled(false);
    				EmailWindow.show();
    			} else {
    				isc.say("Unsuccessful request.");
    			}
    		},
    		
    	});
        
    Log.logDebug("***END***END***END*** MeetingForm.CreateAgendaButton.Click")

    That is does not fire is born out by the developer console log.
    Code:
    16:36:20.681:MUP2:DEBUG:Log:****servlet version*** MeetingForm.CreateAgendaButton.Click
    16:36:20.682:MUP2:DEBUG:Log:*** old[Agenda]PrintOptions: {
        "Options":{...
    }
    16:36:20.846:MUP2:DEBUG:Log:***END***END***END*** MeetingForm.CreateAgendaButton.Click
    I tried using the examples under RPCManager. They had a callback parameter with a string that invoked a named callback function defined in the statement following the sendRequest call. That did not work, either.

    It has been a while since I ran into a problem. But, I really need help with this one.

    Thanks,

    Rick

    P.S. I am running SmartClient Version: v8.2p_2013-01-14/EVAL Development Only on Mozilla Firefox 12.0 with Firebug using Windows XP Pro 32 bit.

    #2
    Callbacks do not fire for download operations because there is no way for the browser to be notified of completion. You will need to rearrange your logic to avoid needing a callback.

    Comment


      #3
      Yipes! this aspect of downloadResult is even in the docs.

      Rearranging my logic is easier said than done. But, I am trying. I have successfully made the callback fire. And, it works great. It opens a new window and populates its form fields from the response headers.

      Here is the frustration: I can see the PDF file contents in the response httpResponseText and the intended file name in the Content-Disposition header. So, I have been looking how to implement my own hiddenFrame transport and, duh, save the contents in a new file with that name.

      Seems the original intent of the world-wide web to download files is not natively implemented in browers in an independent way. HTML5 has a saveAs that might work if I could find a way to access the browser window as an object.

      I imagine if this was easy, downloadResult would work with callback.

      Any ideas?

      Rick

      Comment


        #4
        It's very very hard, and generally speaking, cannot be achieved purely browser side, and must be implemented by having the server monitor the streaming of bytes to the client (tricky in itself) and polling the server to check for download completion while the download occurs.

        In other words, much harder than rearranging your logic and/or screen flow to avoid relying on a callback.

        Comment


          #5
          Actually, I solved it mostly on the browser side. All I did on the server was take the data that I was passing in the response headers and insert it into the already open database in a separate table. I used a unique random key calculated in the browser code and passed in the request as a parameter.

          Then, after the request returns, and waiting for the result to be downloaded, I recursively call setTimeout and keep checking to see if the database record had been inserted yet.

          The attempt that first finds the record present then opens its data in a new window for the user.

          Code:
          	var form = MeetingForm;
          	
          	var oldPrintOptions = form.getValue("AgendaPrintOptions"); 		
          	var vmOptions = meetingTypeVM.getValues().Agenda.Options; 
          	var vmNewOptions = vmOptions.Agenda.Options;	
          	var vmTopic = meetingTypeVM.getValues().Agenda.Topic;
          	var vmNewTopic = vmTopic.Agenda.Topic;
          	var vmIssue = meetingTypeVM.getValues().Agenda.Issue;
          	var vmNewIssue = vmIssue.Agenda.Issue;	
          	var vmTask = meetingTypeVM.getValues().Agenda.Task;
          	var vmNewTask = vmTask.Agenda.Task;	
          	var vmSpecial = meetingTypeVM.getValues().Agenda.Special;
          	var vmNewSpecial = vmSpecial.Agenda.Special;	
          	var vmNewPrintOptions = { Options: vmNewOptions, Topic: vmNewTopic, Issue: vmNewIssue, Task: vmNewTask, Special: vmNewSpecial  };
          	var newPrintOptions = isc.JSON.encode(vmNewPrintOptions);		
          	if (oldPrintOptions != newPrintOptions) { 
          		form.changesPending = true;
          		form.setValue("AgendaPrintOptions", newPrintOptions);
          	}
          
          	var meetingDate;
          	meetingDate = String(form.getValue("MeetingDate"));
          	if (meetingDate == "undefined") meetingDate = ""; 
          	var meetingTime;
          	meetingTime = String(form.getValue("MeetingTime"));
          	if (meetingTime == "undefined") meetingTime = ""; 
          	
          	var d = new Date();
          	var minOffset = d.getTimezoneOffset();
          	var s;
          	if (minOffset < 0) {
          		s = "+"; minOffset = -1 * minOffset;
          	} else {
          		s = "-";
          	}
          	var hrs = 100 + (minOffset / 60);
          	var mins = 100 + minOffset - ( (hrs - 100) * 60);
          	var timeZoneOffset = s + hrs.toString().substring(1) + ":" + mins.toString().substring(1);
          	
          	var emailsKey = Math.floor((Math.random()*1000000000)+1);
          	
          	form.setValue("emailsKey", emailsKey);
          	
          	RPCManager.sendRequest({
          		httpMethod: "POST",
          		actionURL: "/servlet/MeetingAgendaServlet11",
          		params: {	meetingDate:		meetingDate,
          					meetingTime:		meetingTime,
          					timeZoneOffset:		timeZoneOffset,
          					emailsKey:			String(emailsKey),			
          					meetingTypeID:		String(Application.currentMeetingTypeID),
          					agendaPrintOptions: String(form.getValue("AgendaPrintOptions")),
          			},
          		downloadResult: true, 
          		downloadToNewWindow:false,
          		useSimpleHttp: true,			
          	});
          
          	var attempts = 0;  //will be used to max out attempts
          	var timeout = 250; //milliseconds that will double with each attempt
          	
          	Log.logDebug("***EmailsExchange record fetch attempt " + attempts);
          	
          	function tryAgain() {
          		attempts = attempts + 1;
          		EmailsExchange.fetchRecord( emailsKey, 
          			function (dsResponse, data, dsRequest) {
          				if (dsResponse.status >= 0) {
          					if (dsResponse.totalRows == 1) {
          						var rec = {};
          						rec = data[0]; // first and only record
          						EmailForm.editRecord(rec);
          						EmailWindow.show();
          						form.getItem("GetEmailsButton").setDisabled(false);	
          					} else { 
          						if (attempts < 10) {
          							timeout = timeout * 2;
          							setTimeout(tryAgain, timeout);
          						} else {
          							isc.say("Maximum attempts reached for fetching emails.");
          						}
          					}		
          				} else { 
          					if (attempts < 10) {
          						timeout = timeout * 2;
          						setTimeout(tryAgain, timeout);
          					} else {
          						isc.say("Maximum attempts reached for fetching emails.");
          					}
          				}
          			} 	// end of fetchRecord function
          		); 	// end of fetchRecord call
          	} // end of tryAgain
          	
          	tryAgain();
          If you never are able to get downloadresult to work with callbacks, I will understand. Such a callback would have to wait a long time for big files to download.

          Thanks for all the quick replies and helpful comments. This application is getting bigger and more complex. The sooner I can abandon the XML, the better. Still some technology to implement yet.

          Rick

          Comment

          Working...
          X