Ajax POST with Fragment Controller

Hi.

I’ve created a new module, which has the main purpose of upload a file. Following your documentation(I think appframewrok documentation), I’ve created a page.gsp, and upload.gsp, and the UploadFragmentController.

On this Upload fragment, I’m using ajax to make a POST request to my fragment controller, and I’m able to upload the file to the server, however I don’t understand how can return a response with something I want, instead the whole html, as is hapenning.

It seems that under the hood, app framework generates that response, but is it possible to send a custom one?

Thanks

What is the return value of your fragment controller?

Does it look like this? https://github.com/openmrs/openmrs-module-uicommons/blob/master/omod/src/main/java/org/openmrs/module/uicommons/fragment/controller/GlobalPropertiesFragmentController.java

or this? https://github.com/openmrs/openmrs-module-uicommons/blob/master/omod/src/main/java/org/openmrs/module/uicommons/fragment/controller/MessagesFragmentController.java

@dkayiwa, thanks for your answer. After trying your suggestion, I’m getting a ClassCastException, with the following message org.openmrs.ui.framework.SimpleObject cannot be cast to java.lang.String.

Any idea, how can I solve it?

Are you getting any errors in the logs? Could we see how you are making the ajax call?

I’m making the ajax call this way:

this.uploadFile = function() {
	$.ajax({
		url : '',
		type : 'POST',

		// Form data
		data : new FormData($('#uploadProvidersScheduleForm')[0]),

		cache : false,
		contentType : false,
		processData : false,
		success: function(data) {
			console.log(data);
		}
	});
};

Ok, the exception is the following:

ERROR - PageController.handlePath(155) |2017-03-21 14:18:05,903| Error rendering page view for kbips. Model properties:
sessionContext 
featureToggles 
patient 
ui 
context 
contextPath 
session 
param 
out
org.openmrs.ui.framework.ViewException: Error rendering page view for kbips. Model properties:
sessionContext 
featureToggles 
patient 
ui 
context 
contextPath 
session 
param 
out
at org.openmrs.ui.framework.page.GroovyPageView.render(GroovyPageView.java:55)
at org.openmrs.ui.framework.page.PageFactory.processThisFragment(PageFactory.java:187)
at org.openmrs.ui.framework.page.PageFactory.process(PageFactory.java:116)
at org.openmrs.ui.framework.page.PageFactory.handle(PageFactory.java:86)
at org.openmrs.module.uiframework.PageController.handlePath(PageController.java:116)
at org.openmrs.module.uiframework.PageController.handleUrlWithDotPage(PageController.java:83)
at sun.reflect.GeneratedMethodAccessor684.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:177)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:446)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:434)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.openmrs.module.web.filter.ModuleFilterChain.doFilter(ModuleFilterChain.java:72)
at org.openmrs.module.owa.filter.OwaFilter.doFilter(OwaFilter.java:57)
at org.openmrs.module.web.filter.ModuleFilterChain.doFilter(ModuleFilterChain.java:70)
at org.openmrs.module.web.filter.ModuleFilter.doFilter(ModuleFilter.java:54)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.openmrs.web.filter.OpenmrsFilter.doFilterInternal(OpenmrsFilter.java:108)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.orm.hibernate4.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:150)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:105)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:105)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:105)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassCastException: org.openmrs.ui.framework.SimpleObject cannot be cast to java.lang.String
at org.openmrs.ui.framework.fragment.FragmentFactory.processThisFragment(FragmentFactory.java:171)
at org.openmrs.ui.framework.fragment.FragmentFactory.process(FragmentFactory.java:124)
at org.openmrs.ui.framework.page.PageContext.includeFragment(PageContext.java:75)
at org.openmrs.ui.framework.UiUtils.includeFragment(UiUtils.java:152)
at org.openmrs.ui.framework.UiUtils$includeFragment$0.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133)
at SimpleTemplateScript142.run(SimpleTemplateScript142.groovy:27)
at groovy.text.SimpleTemplateEngine$SimpleTemplate$1.writeTo(SimpleTemplateEngine.java:168)
at groovy.text.SimpleTemplateEngine$SimpleTemplate$1.toString(SimpleTemplateEngine.java:180)
at org.openmrs.ui.framework.page.GroovyPageView.render(GroovyPageView.java:43)
... 61 more

Can i look at your controller?

@dkayiwa, here is it:

public class UploadFileFragmentController {

public void get() {
}

public SimpleObject post(FragmentModel model, @SpringBean("userService") UserService service,
        @RequestParam("file") MultipartFile file, HttpServletRequest request, UiUtils ui, UiSessionContext sessionContext) {
	
	SimpleObject ret = new SimpleObject();
	
	if (!file.isEmpty()) {
		
		EnumSupportedFormats format = EnumSupportedFormats.getFormatByMimetype(file.getContentType());
		if (null == format) {
			ret.put("error", ui.message("kbips.importSchedule.invalidFormat"));
			return ret;
		}
		
		FileParser fileparser = FileParserFactory.getFileParser(format);
		
		List<BulkDataRecord> bulkRecords = null;
		try {
			bulkRecords = fileparser.read(file.getInputStream());
			Context.getService(KbipsService.class).saveBulkProvidersSchedule(bulkRecords,
			    sessionContext.getSessionLocation());
		}
		catch (IOException e) {
			throw new IllegalStateException("Problem getting file inputstream");
		}
		
		ret.put("success", ui.message("kbips.importSchedule.importedRecords", bulkRecords.size()));
	} else {
		ret.put("error", ui.message("kbips.importSchedule.emptyFile"));
	}
	return ret;
}
}

Is your entire module somewhere like on github for us to look at? It would be great to also include the exact steps to reproduce.

@dkayiwa it isnt’. If you want I can send you the module source code to you. Maybe zipped to an email? Do you have any other suggestion?

Thanks

Hi @dkayiwa, finally I understand what happened. It was a combination of behaviours that confused me. When I gave the name post to my controller method, and passed empty string as url, to my ajax, the controller method is invoked. It leads me to thought I was correctly invoking the url, but as said before I was always getting the String cast exception. So, now, after looking again for this wiki, I’ve changed the controller method to uploadFile, and on client side, I got the url using ui.actionLink(“uploadFile”). After this changes I was able to get the JSON object on client side.

Many thanks for your help. :slight_smile:

1 Like

Oh i see! Thanks for updating me and saving me the time i would spend investigating this when you already had the solution. :smile: