My CFClient Proof Of Concept and GapDebug

My CFClient Proof Of Concept and GapDebug

Posted by Brad Wood
Jan 07, 2015 21:18:00 UTC

So, in my first entry I discussed that I'm trying my hand at CFClient, mostly drawn to the idea of winning a $1000 gift card from Adobe.  Previously I followed Ram's YouTube videos and articles on setting up a Mobile project in ColdFusion Builder, installing his sample app, compiling that app via Adobe's cloud-based PhoneGap server, and installing it.

This venture was met with mixed success.  The PhoneGap shell app which allows one to test without needing to recompile after EVERY code change fell flat out of the gate for me.  I'm still waiting to hear back from Adobe on that.  I was able to compile and run the sample app, but couldn't get the file APIs to work.  I've sort of given up on that for now-- there's just not enough time to keep banging my head on that wall for the time being.

Weinre --> GapDebug

Using the Weinre server in ColdFusion was actually pretty easy. You just enable and start it in the administrator.  Then you  add ?inspect to your URLS in the PhoneGap shell, or create an "inspect build" when you compile.  This is basically like Chrome's debugging tools, just remotely for the page as it's running on the phone.  

Ray Camden told me in a Twitter conversation that Weinre was yesterday's stale bread and GapDebug is the new hotness.  Not being one to second-guess Ray Camden, I installed GapDebug but two things initially prevented me from using it:

  1. It's internal debugger runs on port 8080, which I also use for Railo.  This is easily changed under "Settings" > "Debugger" > "Network Settings".  Switch from System assigned port to User assigned port.  It typed in 8085 since I knew that port would be free on my system.
  2. GapDebug requires Android 4.4 or higher.  I had rooted my phone last year while out of the country to a modem that would unlock other SIM cards.  As such, my Sprint OTA updates were behind.  After download and reflashing the 1.4 GB stock ROM I was able to update to 4.4.2 and was till in business.  Note, even when I was on Android 4.3, GapDebug was still able to install APKs for me which was really nice.

Using GapDebug is pretty freaking simple.  I just open the debugger window from the icon in the system tray, plug in my phone and it shows up in the list.  At this point, I can click the little "down arrow" icon to install an APK directly on the device.  This works even if the app is currently running-- it just closes it.

I've mostly been using the Console part of GapDebug, which gives more information than Weinre did.  The biggie is JS line numbers and stacks.  Also, complex objects such as errors are displayed in a browsable manner instead of just "Object Object".

One thing I'm not totally sure about is if I need to create "debug" or "inspect" builds in CF Builder.  It appears that normal PhoneGap builds can be debugged via GapDebug, but I could easily be missing something.  The instructions also talk about some debugging bits I'm supposed to add to my PhoneGap's config.xml file, but since that's all abstracted away I'm not even quite sure how to view it, and Builder may just be adding it in there for me.  Please chime in if you know the answers to any of that.  For now, I'm just going to keep using it and pushing forward :)

My Entry

So I honestly had a hard time figuring out what the heck to create for my mobile app entry.  I couldn't think of anything very useful or "cool" that wouldn't take a l

ong

 time to write.  Of course, I wanted to try and use at least one or more of the client APIs-- since that was kind of the whole point.  With few examples of CFClient on the Internet, I really just wanted to play with each client API.  

So, with that in mind, I've set out to create a "CFClient Sampler" that will simply demo as many of the client APIs that I have time to implement (and can get working) before the deadline.  This seems like a win-win-win.  

  1. I get to play with all the APIs
  2. My blog entries and GitHub-hosted code will help the community in their future CFClient usage
  3. I'll win $1000

Ok, so I'm not sure about that last one.  Let just call it a "win-win-hopefully-maybe-win" for now :)  I'm currently accepting ideas for an icon-- I'm thinking something with boneless wings and cheese sticks :)

Getting Started

So, using a really stripped down version of the Expense Tracker app, I got a proof of concept going.  I figured the Connection API would be a good place to start.  It only has 3 possible calls:

  1. cfclient.connection.getType()
  2. cfclient.connection.onOffline()
  3. cfclient.connection.onOnline()

The docs are found here:

https://wikidocs.adobe.com/wiki/display/coldfusionen/Connection+Functions

And the Adobe-provided examples are found here:

https://wikidocs.adobe.com/wiki/display/coldfusionen/Using+the+Connection+APIs

So, first things first-- you have to add "connection" as a "feature" to your app first or it won't work.  Two things about this:

  1. There is a nice UI in CFBuilder which basically just dynamically generates the config.xml file, but why can't CFBuilder just do this for me?  When it compiles the app, can't it just look and see if I'm using the "connection" API, and if so just add it?
  2. If you forget to add this feature, the error you get will make no sense.  The "cfclient.connection" object will exist, but it will have no getTypes() method on it.  Enabling the connection feature will make the method magically appear.  It took me a few minutes to figure that one out.

Right click on your project, and choose "properties".  Then under "ColdFusion Mobile Project", choose the "PhoneGap" tab and click "New...".

Choose "Feature" on the left.  Then check the "Connection" box and hit "OK" twice.

For my app, I just included jQuery and jQuery Mobile and a super simple body:

<h1>CFClient Sampler</h1>
<h3 id="connectionOnlineStatus"></h3>
Your internet connection is: <span style="font-weight: bold;" id="connectionType"></span>
<button id="btnRefreshConnection">Manual Refresh</button>

 

In Ram's example, he had an app.js file that just bound all the UI elements to "CFClient functions" in his CFM file.  Honestly, I'm not sure I see the point in that since everything inside your CFClient tags essentially IS JavaScript.  It will compile to JS, it will have access to JS objects, it IS JS.  Ignore the fact, that you can use some CFML syntax in there.  I went ahead and just bound by DOM elements in my CFClient block.  

For now, I'm not even using an include-- it's all just the in the index.cfm.  I wanted to get it working first, and then see about how to abstract it back out later.  The code outputs your current connection type-- none, wifi, 3g, 4g, etc.  There are also two listeners-- one that fires any time your device goes offline and one that fires when it comes back online.  Notes:

  • The docs say getType() returns a number.  Wrong, it returns a string such as "3g", "4g", "none".  Perhaps this changed at some time. Use the "pseudo constants" cfclient.connection.UNKNOWN, cfclient.connection.ETHERNET, cfclient.connection.WIFI etc to avoid hard-coding.
    Note, the docs are wrong there. The constant names are Connection.UNKNOWN, Connection.ETHERNET, Connection.WIFI, etc
  • My device sometimes goes offline for a second when switching off of wifi
  • My device will go online several times in a row without ever going off when switching naturally between 3G, 4G, and Wifi.  I'm sure that's working as designed, just something to keep in mind.
  • The refresh button, in theory, is unnecessary since the callbacks should always keep the UI up to date.
  • The try/catch is because errors seem unintelligible if I let them go uncaught.  Logging the error object seems to be a much better way to debug them.
<cfclient>
	<cfscript>
		try {
			// When user clicks the manual refresh button
			$(document).on("click","##btnRefreshConnection", function(){
				loadConnectionDetails();				
			});
			
			// Display the connection type
			function loadConnectionDetails() {
				$("##connectionType").text( cfclient.connection.getType() );				
			}
			
			// I'm fired every time the device goes offline
			function onConnectionOffline() {
				loadConnectionDetails();
				$("##connectionOnlineStatus").text( 'Offline' );
				$("##connectionOnlineStatus").css("color","red");
			}
			
			// I'm fired every time the device goes online
			function onConnectionOnline() {
				loadConnectionDetails();
				$("##connectionOnlineStatus").text( 'Online' );
				$("##connectionOnlineStatus").css("color","green");
			}
			
			// Bind the functions to call when the devices connection state changes.
			cfclient.connection.onOffline( 'onConnectionOffline' );
			cfclient.connection.onOnline( 'onConnectionOnline' );
			
			
			
		} catch( any e ) {
			console.log( e );
		}
	  	
	</cfscript>
</cfclient>

Here's some screenshots of my simple, yet effective CFClient Sampler app so far.  

That's it for today.  My code is on GitHub and I will be creating a tag and release for each blog post.  View this tag (0.1) here:

https://github.com/bdw429s/CFClient-Sampler/tree/0.1

You can also download the APK file and try it out on your Android phone here:

https://github.com/bdw429s/CFClient-Sampler/releases

And as always, my code comes with no warranties and will probably publish all your inappropriate photos to a public instagram account.

Error translating markup widget: The content slug 'cfclient-series-list' does not exist lucee.runtime.exp.CustomTypeException: The content slug 'cfclient-series-list' does not exist at lucee.runtime.tag.Throw._doStartTag(Throw.java:212) at lucee.runtime.tag.Throw.doStartTag(Throw.java:201) at throw_cfm$cf.udfCall(/throw.cfm:11) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.functions.system.CFFunction.call(CFFunction.java:109) at widgets.contentstore_cfc$cf.udfCall(/contentbox/widgets/ContentStore.cfc:60) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:685) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:572) at lucee.runtime.ComponentImpl.callWithNamedValues(ComponentImpl.java:1930) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:900) at lucee.runtime.functions.dynamicEvaluation.Invoke.call(Invoke.java:49) at models.content.renderers.widgetrenderer_cfc$cf$6g.udfCall(/contentbox/models/content/renderers/WidgetRenderer.cfc:233) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.type.scope.UndefinedImpl.callWithNamedValues(UndefinedImpl.java:802) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:866) at lucee.runtime.PageContextImpl.getFunctionWithNamedValues(PageContextImpl.java:1766) at models.content.renderers.widgetrenderer_cfc$cf$6g.udfCall(/contentbox/models/content/renderers/WidgetRenderer.cfc:32) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.type.scope.UndefinedImpl.callWithNamedValues(UndefinedImpl.java:802) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:866) at lucee.runtime.PageContextImpl.getFunctionWithNamedValues(PageContextImpl.java:1766) at models.content.renderers.widgetrenderer_cfc$cf$6g.udfCall(/contentbox/models/content/renderers/WidgetRenderer.cfc:20) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:685) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:572) at lucee.runtime.ComponentImpl.callWithNamedValues(ComponentImpl.java:1930) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:900) at lucee.runtime.functions.dynamicEvaluation.Invoke.call(Invoke.java:49) at system.web.context.interceptorstate_cfc$cf.udfCall2(/coldbox/system/web/context/InterceptorState.cfc:515) at system.web.context.interceptorstate_cfc$cf.udfCall(/coldbox/system/web/context/InterceptorState.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.type.scope.UndefinedImpl.callWithNamedValues(UndefinedImpl.java:802) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:866) at lucee.runtime.PageContextImpl.getFunctionWithNamedValues(PageContextImpl.java:1766) at system.web.context.interceptorstate_cfc$cf.udfCall1(/coldbox/system/web/context/InterceptorState.cfc:360) at system.web.context.interceptorstate_cfc$cf.udfCall(/coldbox/system/web/context/InterceptorState.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.type.scope.UndefinedImpl.callWithNamedValues(UndefinedImpl.java:802) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:866) at lucee.runtime.PageContextImpl.getFunctionWithNamedValues(PageContextImpl.java:1766) at system.web.context.interceptorstate_cfc$cf.udfCall1(/coldbox/system/web/context/InterceptorState.cfc:148) at system.web.context.interceptorstate_cfc$cf.udfCall(/coldbox/system/web/context/InterceptorState.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:685) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:572) at lucee.runtime.ComponentImpl.callWithNamedValues(ComponentImpl.java:1930) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:866) at lucee.runtime.PageContextImpl.getFunctionWithNamedValues(PageContextImpl.java:1766) at system.web.services.interceptorservice_cfc$cf.udfCall1(/coldbox/system/web/services/InterceptorService.cfc:201) at system.web.services.interceptorservice_cfc$cf.udfCall(/coldbox/system/web/services/InterceptorService.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:685) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:572) at lucee.runtime.ComponentImpl.callWithNamedValues(ComponentImpl.java:1930) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:900) at lucee.runtime.functions.dynamicEvaluation.Invoke.call(Invoke.java:49) at system.ioc.provider_cfc$cf.udfCall(/coldbox/system/ioc/Provider.cfc:110) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.call(UDFImpl.java:217) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:684) at lucee.runtime.ComponentImpl.onMissingMethod(ComponentImpl.java:611) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:574) at lucee.runtime.ComponentImpl.call(ComponentImpl.java:1911) at lucee.runtime.util.VariableUtilImpl.callFunctionWithoutNamedValues(VariableUtilImpl.java:787) at lucee.runtime.PageContextImpl.getFunction(PageContextImpl.java:1747) at models.content.basecontent_cfc$cf$2o.udfCall8(/contentbox/models/content/BaseContent.cfc:1601) at models.content.basecontent_cfc$cf$2o.udfCall(/contentbox/models/content/BaseContent.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.call(UDFImpl.java:217) at lucee.runtime.type.scope.UndefinedImpl.call(UndefinedImpl.java:785) at lucee.runtime.util.VariableUtilImpl.callFunctionWithoutNamedValues(VariableUtilImpl.java:787) at lucee.runtime.PageContextImpl.getFunction(PageContextImpl.java:1747) at models.content.basecontent_cfc$cf$2o.udfCall8(/contentbox/models/content/BaseContent.cfc:1574) at models.content.basecontent_cfc$cf$2o.udfCall(/contentbox/models/content/BaseContent.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.call(UDFImpl.java:217) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:684) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:572) at lucee.runtime.ComponentImpl.call(ComponentImpl.java:1911) at lucee.runtime.util.VariableUtilImpl.callFunctionWithoutNamedValues(VariableUtilImpl.java:787) at lucee.runtime.PageContextImpl.getFunction(PageContextImpl.java:1747) at models.system.cbhelper_cfc$cf$4c.udfCall7(/contentbox/models/system/CBHelper.cfc:925) at models.system.cbhelper_cfc$cf$4c.udfCall(/contentbox/models/system/CBHelper.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.call(UDFImpl.java:217) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:684) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:572) at lucee.runtime.ComponentImpl.call(ComponentImpl.java:1911) at lucee.runtime.util.VariableUtilImpl.callFunctionWithoutNamedValues(VariableUtilImpl.java:787) at lucee.runtime.PageContextImpl.getFunction(PageContextImpl.java:1747) at modules.contentbox.themes._default.views._blogincludes_cfm$cf.call(/modules/contentbox/themes/default/views/_blogIncludes.cfm:11) at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1034) at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:926) at lucee.runtime.PageContextImpl.doInclude(PageContextImpl.java:907) at system.web.rendererencapsulator_cfm$cf.call(/coldbox/system/web/RendererEncapsulator.cfm:54) at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1034) at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:926) at lucee.runtime.PageContextImpl.doInclude(PageContextImpl.java:918) at lucee.runtime.tag.CFTag.doInclude(CFTag.java:319) at lucee.runtime.tag.CFTag.cfmlStartTag(CFTag.java:245) at lucee.runtime.tag.CFTag.doStartTag(CFTag.java:179) at system.web.renderer_cfc$cf.udfCall1(/coldbox/system/web/Renderer.cfc:469) at system.web.renderer_cfc$cf.udfCall(/coldbox/system/web/Renderer.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.call(UDFImpl.java:217) at lucee.runtime.type.scope.UndefinedImpl.call(UndefinedImpl.java:785) at lucee.runtime.util.VariableUtilImpl.callFunctionWithoutNamedValues(VariableUtilImpl.java:787) at lucee.runtime.PageContextImpl.getFunction(PageContextImpl.java:1747) at system.web.renderer_cfc$cf.udfCall1(/coldbox/system/web/Renderer.cfc:329) at system.web.renderer_cfc$cf.udfCall(/coldbox/system/web/Renderer.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:685) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:572) at lucee.runtime.ComponentImpl.callWithNamedValues(ComponentImpl.java:1930) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:866) at lucee.runtime.PageContextImpl.getFunctionWithNamedValues(PageContextImpl.java:1766) at system.web.renderer_cfc$cf.udfCall1(/coldbox/system/web/Renderer.cfc:149) at system.web.renderer_cfc$cf.udfCall(/coldbox/system/web/Renderer.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:685) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:572) at lucee.runtime.ComponentImpl.callWithNamedValues(ComponentImpl.java:1930) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:866) at lucee.runtime.PageContextImpl.getFunctionWithNamedValues(PageContextImpl.java:1766) at models.system.cbhelper_cfc$cf$4c.udfCalld(/contentbox/models/system/CBHelper.cfc:2015) at models.system.cbhelper_cfc$cf$4c.udfCall(/contentbox/models/system/CBHelper.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.call(UDFImpl.java:217) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:684) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:572) at lucee.runtime.ComponentImpl.call(ComponentImpl.java:1911) at lucee.runtime.util.VariableUtilImpl.callFunctionWithoutNamedValues(VariableUtilImpl.java:787) at lucee.runtime.PageContextImpl.getFunction(PageContextImpl.java:1747) at modules.contentbox.themes._default.layouts.blog_cfm$cf.call(/modules/contentbox/themes/default/layouts/blog.cfm:9) at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1034) at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:926) at lucee.runtime.PageContextImpl.doInclude(PageContextImpl.java:907) at system.web.rendererencapsulator_cfm$cf.call(/coldbox/system/web/RendererEncapsulator.cfm:54) at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1034) at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:926) at lucee.runtime.PageContextImpl.doInclude(PageContextImpl.java:918) at lucee.runtime.tag.CFTag.doInclude(CFTag.java:319) at lucee.runtime.tag.CFTag.cfmlStartTag(CFTag.java:245) at lucee.runtime.tag.CFTag.doStartTag(CFTag.java:179) at system.web.renderer_cfc$cf.udfCall1(/coldbox/system/web/Renderer.cfc:469) at system.web.renderer_cfc$cf.udfCall(/coldbox/system/web/Renderer.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.type.scope.UndefinedImpl.callWithNamedValues(UndefinedImpl.java:802) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:866) at lucee.runtime.PageContextImpl.getFunctionWithNamedValues(PageContextImpl.java:1766) at system.web.renderer_cfc$cf.udfCall2(/coldbox/system/web/Renderer.cfc:697) at system.web.renderer_cfc$cf.udfCall(/coldbox/system/web/Renderer.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:685) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:572) at lucee.runtime.ComponentImpl.callWithNamedValues(ComponentImpl.java:1930) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:866) at lucee.runtime.PageContextImpl.getFunctionWithNamedValues(PageContextImpl.java:1766) at system.web.renderer_cfc$cf.udfCall1(/coldbox/system/web/Renderer.cfc:558) at system.web.renderer_cfc$cf.udfCall(/coldbox/system/web/Renderer.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:685) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:572) at lucee.runtime.ComponentImpl.callWithNamedValues(ComponentImpl.java:1930) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:866) at lucee.runtime.PageContextImpl.getFunctionWithNamedValues(PageContextImpl.java:1766) at system.frameworksupertype_cfc$cf.udfCall2(/coldbox/system/FrameworkSupertype.cfc:307) at system.frameworksupertype_cfc$cf.udfCall(/coldbox/system/FrameworkSupertype.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.type.scope.UndefinedImpl.callWithNamedValues(UndefinedImpl.java:802) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:866) at lucee.runtime.PageContextImpl.getFunctionWithNamedValues(PageContextImpl.java:1766) at modules.contentbox.modules.contentbox_ui495.handlers.content_cfc$cf.udfCall(/modules/contentbox/modules/contentbox-ui/handlers/content.cfc:264) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.type.scope.UndefinedImpl.callWithNamedValues(UndefinedImpl.java:802) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:866) at lucee.runtime.PageContextImpl.getFunctionWithNamedValues(PageContextImpl.java:1766) at modules.contentbox.modules.contentbox_ui495.handlers.blog_cfc$cf.udfCall1(/modules/contentbox/modules/contentbox-ui/handlers/blog.cfc:214) at modules.contentbox.modules.contentbox_ui495.handlers.blog_cfc$cf.udfCall(/modules/contentbox/modules/contentbox-ui/handlers/blog.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:685) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:572) at lucee.runtime.ComponentImpl.callWithNamedValues(ComponentImpl.java:1930) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:900) at lucee.runtime.functions.dynamicEvaluation.Invoke.call(Invoke.java:49) at system.web.controller_cfc$cf.udfCall3(/coldbox/system/web/Controller.cfc:1197) at system.web.controller_cfc$cf.udfCall(/coldbox/system/web/Controller.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.type.scope.UndefinedImpl.callWithNamedValues(UndefinedImpl.java:802) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:866) at lucee.runtime.PageContextImpl.getFunctionWithNamedValues(PageContextImpl.java:1766) at system.web.controller_cfc$cf.udfCall3(/coldbox/system/web/Controller.cfc:919) at system.web.controller_cfc$cf.udfCall(/coldbox/system/web/Controller.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.type.scope.UndefinedImpl.callWithNamedValues(UndefinedImpl.java:802) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:866) at lucee.runtime.PageContextImpl.getFunctionWithNamedValues(PageContextImpl.java:1766) at system.web.controller_cfc$cf.udfCall3(/coldbox/system/web/Controller.cfc:658) at system.web.controller_cfc$cf.udfCall(/coldbox/system/web/Controller.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.callWithNamedValues(UDFImpl.java:207) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:685) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:572) at lucee.runtime.ComponentImpl.callWithNamedValues(ComponentImpl.java:1930) at lucee.runtime.util.VariableUtilImpl.callFunctionWithNamedValues(VariableUtilImpl.java:866) at lucee.runtime.PageContextImpl.getFunctionWithNamedValues(PageContextImpl.java:1766) at coldbox.system.bootstrap_cfc$cf.udfCall1(/coldbox/system/Bootstrap.cfc:292) at coldbox.system.bootstrap_cfc$cf.udfCall(/coldbox/system/Bootstrap.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.call(UDFImpl.java:217) at lucee.runtime.type.scope.UndefinedImpl.call(UndefinedImpl.java:785) at lucee.runtime.util.VariableUtilImpl.callFunctionWithoutNamedValues(VariableUtilImpl.java:787) at lucee.runtime.PageContextImpl.getFunction(PageContextImpl.java:1747) at coldbox.system.bootstrap_cfc$cf.udfCall1(/coldbox/system/Bootstrap.cfc:509) at coldbox.system.bootstrap_cfc$cf.udfCall(/coldbox/system/Bootstrap.cfc) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.call(UDFImpl.java:217) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:684) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:572) at lucee.runtime.ComponentImpl.call(ComponentImpl.java:1911) at lucee.runtime.util.VariableUtilImpl.callFunctionWithoutNamedValues(VariableUtilImpl.java:787) at lucee.runtime.PageContextImpl.getFunction(PageContextImpl.java:1747) at application_cfc$cf.udfCall(/Application.cfc:170) at lucee.runtime.type.UDFImpl.implementation(UDFImpl.java:106) at lucee.runtime.type.UDFImpl._call(UDFImpl.java:344) at lucee.runtime.type.UDFImpl.call(UDFImpl.java:217) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:684) at lucee.runtime.ComponentImpl._call(ComponentImpl.java:572) at lucee.runtime.ComponentImpl.call(ComponentImpl.java:1911) at lucee.runtime.listener.ModernAppListener.call(ModernAppListener.java:437) at lucee.runtime.listener.ModernAppListener._onRequest(ModernAppListener.java:133) at lucee.runtime.listener.MixedAppListener.onRequest(MixedAppListener.java:44) at lucee.runtime.PageContextImpl.execute(PageContextImpl.java:2460) at lucee.runtime.PageContextImpl._execute(PageContextImpl.java:2450) at lucee.runtime.PageContextImpl.executeCFML(PageContextImpl.java:2421) at lucee.runtime.engine.Request.exe(Request.java:45) at lucee.runtime.engine.CFMLEngineImpl._service(CFMLEngineImpl.java:1179) at lucee.runtime.engine.CFMLEngineImpl.serviceCFML(CFMLEngineImpl.java:1125) at lucee.loader.engine.CFMLEngineWrapper.serviceCFML(CFMLEngineWrapper.java:97) at lucee.loader.servlet.CFMLServlet.service(CFMLServlet.java:51) at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:764) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Unknown Source)

 


Steve Sommers

Thanks Brad. Nice start. I fully agree with your statement "Honestly, I'm not sure I see the point in that since everything inside your CFClient tags essentially IS JavaScript." If you want you can delete my last post on the other thread as Ram's example is good at showing everything that is possible with CFClient, it just was not the example I was looking for. I don't want to be the "dump on Ram guy." PM me if your not 100% satisfied with your $1000 entry direction -- we can split it (jk, I'll let you have it -- but you got to win).

Brad Wood

Steve, I think your comments were fine. The fact of the matter is, this IS all a little confusing to figure out. I don't think it was due to Ram not thinking it through so much as it being a paradigm shift and he was mixing several techniques for the sake of the example.

It's sort of like when you first learned ColdFusion and you were confused about when your JavaScript code executed and when your CFML code executed. It's that all over again. Even the CFAjaxProxy tags weren't too bad because the tag simply spit out some JavaScript. This this case you have actual "CFML" that's going to be cross-compiled to JavaScript so you get a little turned around literally calling JavaScript objects from CFML and CFML functions from JavaScript.

I'll write more about this later after I've formed a better opinion, but I DO like the cfclient API -- especially its synchronous nature. I just wish it was presented as a straight-up JavaScript library that I called in a JS script block. The only compelling part about CFML in JS that I've found so far is CFQuery.

Brad Wood

Oh, I forgot to add-- I'd love to hear any ideas you have for the app. If there's something else you'd like to see built I would encourage you to give it a shot and make your own entry The worst that could happen is you have some fun :)

Site Updates

Entry Comments

Entries Search