My new adventure

Well,

For those of you not listening to the podcast, www.cfhour.com, after many years at Disney I decided to change jobs. Leaving Disney was not a decision I took lightly. The decision process caused many sleepless nights and many moments of panic. But with the help of family and friends I was, obviously, able to make a final decision.

I have to say, leaving somewhere you have been for just shy of 11 years is tough. There is nothing that can prepare you for that day you resign nor the last day at work. I wish all the best to those friends I left behind at Disney. I know they will go forth and blaze a path on on their own.

So, what am I doing now? Well, I am now a Sr. Developer at Nonfat Media. I am very excited about the future and what lies ahead. It is a strange place to be at the moment. I am coming from somewhere where I had all the answers to somewhere I have to ask all the questions. Once I get my bearings and get some knowledge I know I will be able to help do great things here.

So, what about my blog (haven't blogged in a while) and the podcast? They will both continue on. I have gotten permission to talk and blog about things that I do here (with some restrictions). So, I hope that along my new journey of learning I will be able to teach others as well.

Till next time...

--Dave

jQMobile version 1 and ThemeRoller released

I must have been sleeping under a rock because I missed the release announcement.

jQuery Mobile version 1 is finally released. You can read all about it here... http://jquerymobile.com/blog/2011/11/16/announcing-jquery-mobile-1-0/

Congrats to all involved on creating such a great product.

ThemeRoller for jQuery mobile was released as well. If you were at Adobe MAX 2011 you probably saw it demoed there. Initially I was very excited about the tool. However, after 5 minutes with it I was kinda bummed out. But, take a look at it and form your own opinion... http://jquerymobile.com/themeroller/

Till next time,

--Dave

CSV File Reading using cfhttp

So, it was asked on twitter if cfspreadsheet could read a csv file. I quickly looked at the docs and it appeared to me that it could. The docs even had this example..

view plain print about
1<cfspreadsheet action="read" src="#theFile#" sheet=1 row="3,4" format="csv" name="csvData">

However, if you try and do that you get this error:

view plain print about
1An error occurred while reading the Excel: java.lang.IllegalArgumentException: Your InputStream was neither an OLE2 stream, nor an OOXML stream.

So, what I figured out was that cfspreadsheet type="csv" just converts the read xls document into csv format. Not sure how usefull that is.

So, I started digging into a possible solution. Then I stumbled into something. I ran into a post that talked about using cfhttp to load the csv. So, that got me thinking and I ended up with this.

view plain print about
1<cfhttp method="get" url="http://path.to.csv.file/test.csv" name="csvData">
2
3<cfoutput>#isQuery(csvData)#</cfoutput>
4
5<cfloop query="csvdata" >
6    <p>
7<cfloop list="#csvdata.columnlist#" index="i">
8    <cfoutput>
9            #csvdata['#i#'][currentRow]# -
10    </cfoutput>    
11</cfloop>
12</p>
13</cfloop>

I was shocked that the isQuery returned true. So, since it uses the first row as the column names I write some code to loop over the data and out put it. I honestly didn't think that this would work. I just get totally excited when something that I thought would be hard became super easy thanks to ColdFusion.

I have only ran this against ColdFusion 9 so I am not sure about backwards compatibility.

UPDATE: If the column name contains a space an error will be thrown. The error happens in the cfhttp tag call so you can't correct them post call. Make sure that if you are doing this that your first row contains text that are column name formatted. I.e... use "my_date" instead of "my date".

Till next time...

--Dave

ColdFusion Developer Week Recording

If you happened to miss my ColdFusion Developer week presentation on ColdFusion and Mobile you are in luck. You can just go here: http://adobe.ly/q7XIgC and watch it. Or watch it again if you where there. This is an edited version with the audio drop out section removed.

If you want to watch any of the other presentations from the week you can find the full list of them here: http://www.adobe.com/devnet/coldfusion/events.html

Till next time...

--Dave

Adobe ColdFusion Developer Week slides and code

Sorry for the delay everyone. Here are the slides and the code for my Adobe Developer Week presentation on ColdFusion and Mobile.

Its JSON, I swear

I am mostly bogging this so I don't forget this stupid mistake I made. I am using jQuery to make an ajax call to a CFC. The CFC returns json data that I am using to populate a form.

The call worked just find and data was returned. However, for some reason, in JavaScript the JSON data was not being treated as JSON. I spent ages searching for solutions and doing trial and error.

This is the JavaScript call I was making:

view plain print about
1function getDetail(item){
2 $.ajax({
3 url: '/components/packages.cfc?method=getPackageByID',
4 cache: false,
5 type: "get",
6 data: {
7 packageid: item
8 },
9 success: function(data){
10 console.log(data.DATA);
11 }
12 });
13 }

This is the CFC that returned JSON.

view plain print about
1<cffunction name="getPackageByID" access="remote" returnformat="JSON" >
2        <cfargument name="packageid" required="true" type="numeric" >
3        
4        <cfset var getdata = "">
5        
6        <cfquery name="getdata" datasource="#request.dsn#" >
7            select * from package
8            where packageid = <cfqueryparam value="#arguments.packageid#" cfsqltype="cf_sql_integer" >
9        </cfquery>
10    
11        <cfreturn getData>
12    </cffunction>

Knowing what I know (which I started to question) I should have been able to use "data.DATA" to get to the JSON data in the result. However, when I output it to the console I would get "undefined". I also tried, among other things, "data[0]" which got me "{".

The lovely kicker was that the Chrome debugger network tab showed the call return as JSON.

I continued to try anything I could think of to get JavaScript to understand the return as JSON. All I ended up doing was finding a ton of ways to not process JSON.

Finally, I figured something out. It finally dawned on me that JavaScript was processing the data as a string not JSON. The "Intelligent Guess" feature of $.ajax() in jQuery was apparently failing to see the data as JSON.

I then added " dataType: 'json' " to the ajax call. Once I did that everything started working as expected.

If there is a moral here I would say it is to not expect data types to be auto assigned correctly. If you can, define what the data types will be. this will save you pain and anguish later.

Till next time...

--Dave

ColdFusion Developer Week

Time to get your learning on.. for FREE. Check out Adobe ColdFusion Developer Week for a weeks full of great sessions for the new and old alike.

I am especially excited about this as I am one of the speakers. I will be talking about ColdFusion and Mobile.

Check it out and sign up. http://www.adobe.com/cfusion/event/index.cfm?event=detail&id=1489920&loc=en_us

Till next time,

--Dave

Creating XML in ColdFusion

Well.. I ran across this code and wanted to share. I am using it as more of an example of something you probably shouldn't do.

One of the strengths of ColdFusion is to make hard things easy. This code basically ignores that principal and makes hard things harder.

So.. here is the code I found

view plain print about
1<cffile action="WRITE" file="#WallXML#\#NewFile#" output="<?xml version='1.0' encoding='UTF-8'?>" addNewLine="yes" fixnewline="yes" charset="iso-8859-1">
2
3
4<cffile action="APPEND" file="#WallXML#\#NewFile#" output="<gallery xmlns:media='http://search.yahoo.com/mrss/'>" addNewLine="yes" fixnewline="yes">
5
6<cffile action="APPEND" file="#WallXML#\#NewFile#" output="<settings>" addNewLine="yes" fixnewline="yes">
7    <cffile action="APPEND" file="#WallXML#\#NewFile#" output="<mediaFolder type='large' media='image'>media/3dwall/</mediaFolder>" addNewLine="yes" fixnewline="yes">
8    <cffile action="APPEND" file="#WallXML#\#NewFile#" output="<mediaFolder type='thumbnail' media='image'>media/3dwall/thumbs/</mediaFolder>" addNewLine="yes" fixnewline="yes">
9<cffile action="APPEND" file="#WallXML#\#NewFile#" output="</settings>" addNewLine="yes" fixnewline="yes">
10
11    <cfloop query="WallPics">
12            <cffile action="APPEND" file="#WallXML#\#NewFile#" output="<item>" addNewLine="yes" fixnewline="yes">
13                <cffile action="APPEND" file="#WallXML#\#NewFile#" output="<media:text>Tooltip 1</media:text>" addNewLine="yes" fixnewline="yes">
14                <cffile action="APPEND" file="#WallXML#\#NewFile#" output="<media:content url='#Photo#' type='image/jpeg' width='500' height='375' />" addNewLine="yes" fixnewline="yes">
15            <cffile action="APPEND" file="#WallXML#\#NewFile#" output="</item>" addNewLine="yes" fixnewline="yes">    
16    </cfloop>
17
18
19<cffile action="APPEND" file="#WallXML#\#NewFile#" output="</gallery>" addNewLine="yes" fixnewline="yes">

While in principal the code works. An XML file is generated and written to the server. However there are many issues with this.

1: The XML being written replaced an XML document used by a flash object. If the flash object tried to call the XML while it was being written it would error.

2: IF there was an error in XML generation the system would be left with an invalid and incomplete XML document on the server. This would probably cause the flash object to fail.

3: Causes excess I/O to the file system.

So, how did I fix it? Well easy.. ColdFusion has a built in way to create XML. There are a couple ways to do it but I used the tag approach. It just seemed to fit with the current code.

Here is what I ended up with:

view plain print about
1<cfoutput>
2<cfxml variable="theResult">
3<gallery xmlns:media='http://search.yahoo.com/mrss/'>
4    <settings>
5        <mediaFolder type='large' media='image'>media/3dwall/</mediaFolder>
6        <mediaFolder type='thumbnail' media='image'>media/3dwall/thumbs/</mediaFolder>
7    </settings><cfloop query="WallPics">
8        <item>
9            <media:text>Tooltip 1</media:text>
10            <media:content url='#Photo#' type='image/jpeg' width='500' height='375' />
11        </item></cfloop>
12</gallery>
13</cfxml>
14</cfoutput>
15
16<cffile action="write" file="#WallXML#\#NewFile#" output="#theResult#">

Now the code just generates a single XML var and then writes it at once to the server. If something were to go wrong with the generation the existing XML document will be left untouched. Also, since it is a single write the odds of the flash object being impacted by the new XML are drastically reduced.

So, remember, let ColdFusion do what it does. Don't try and work against it and make your lives harder.

Till next time,

--Dave

CFHour Podcast feedback

Since the show is for the people we would like to know what the people want. We do our best to talk about subject that we feel are of interest. However, we may not have hit on something that interestes you. Also, if there is something we are doing that you are not a fan of let us know that as well.

Use the comments below or email us at podcast@cfhour.com and share your thoughts.

Till next time...

--Dave

CFFILE odd behavior

While working to restrict an upload I came across an interesting issue with CFFILE. Lets say that this is your code:

view plain print about
1<cffile action="upload" filefield="Form.Photo" destination="#Path#" nameconflict="makeunique" result="Thumb" accept="image/*">

The "accept" attribute would restrict to only file with an image mime type. The "thumbs" var names in the results attribute will contain the results of the CFFILE action. If the "result" attribute is omitted the results will end up in a "cffile" var.

Lets say a user uploads a text file instead of an image. We need to check to see if cffile processed the file. This is where the odd behavior comes in.

First, an error will be thrown that has to be trapped. There is no "onError" mechanism built into cffile. Easiest thing to do is to wrap it in a cftry. You can then look at the cfcatch.message for the error.

Next, if there was an error and we tried to check the "thumbs" var we would get another error. This is because the var does not exist. However, if you check for a "cffile" var it is an empty struct.

From what I can tell, if the file does not pass the accept check it is not written to the server. This means there is no cleanup to deal with.

So, the moral of this story is that I wish that cffile had an internal way to handle this. I don't think that wrapping it in a cftry is the best solution.

Till next time,

--Dave

More Entries