23 Replies Latest reply: Sep 23, 2010 3:47 AM by Adam Cameron. RSS

    Passing Dates to a cfc

    Daniel Pride Community Member

      I am trying to pass a date to a  cfc and get a numeric response

      I test the service in Flashbuilder and it works fine when I type in a value of 09/20/2010

      It returns the numeric sum as expected....

       

      If I change the cfc to a string and refresh the service this also works (2010/09/20)

       

      But when I try to call it nothing and I mean nothing works.

      Not this....

                         var theDate:Date = new Date();

                         sumDateLineItemsResult.token = lineItemsService.sumDateLineItems(theDate);

                           lineItemsService.commit();

      nor this....
                      sumDateLineItemsResult.token = lineItemsService.sumDateLineItems(new Date(2010,09,20));
                      lineItemsService.commit();

       

      nor a call with a string variable after the cfc has been modified to accept strings....

       

      The cfc...

       

          <cffunction name="sumDateLineItems" output="false" access="remote" returntype="numeric" >
              <cfargument name="theDate" type="date" required="true" />
              <cfset var qSum="">
              <cfquery name="qsum" datasource="BlueRose">
                   SELECT SUM(Price) AS daysTotal FROM LineItems WHERE AptDate =  <CFQUERYPARAM CFSQLTYPE="CF_SQL_DATE"                 VALUE="#ARGUMENTS.theDate#">
              </cfquery>
              <cfif len(qsum.daysTotal) EQ 0>
                  <cfset qsum.daysTotal="0">
              </cfif>
              <cfreturn qsum.daysTotal>   
          </cffunction>

       

      It seems to simple and obvious but I am stumped ! Any help from a coldfusion maven would be greatly appreciated.

      Thanks

      Dan Pride

        • 1. Re: Passing Dates to a cfc
          Owain North Community Member

          Not too sure about the Flash side, but try setting the argument type to "any", then dumping out the arguments scope to an email so you can see exactly what CF receives when you call it.

           

          O.

          • 2. Re: Passing Dates to a cfc
            JR "Bob" Dobbs Community Member

            Are you sure that you are using Actionscript's Date object constructor as intended?  The month parameter should be zero based.

             

            new Date(2010,8,20).

             

            Things to check/try:

             

            1. Is there a communication problem between your Flex client and all services on your CF server or just this one function?

             

            2. Use ServiceCapture or a similar tool to look at what is being sent from the client to the server.

             

            http://www.kevinlangdon.com/serviceCapture/

            • 3. Re: Passing Dates to a cfc
              JaneUK Community Member

              My answer to date-passing issues in any situation is usually to put my date in a clearly-defined string format (YYYYMMDD works well), pass the string, and parse it back into a date at the other end.At the moment, you've got implied conversion, and it may or may not be working the same way all the time.

               

              Just make sure it's date, not string, when it gets into your query, or you'll slow the query down (assuming your date field is indexed).

              • 4. Re: Passing Dates to a cfc
                Daniel Pride Community Member

                That sounds like a great idea, aha ! server side debugging

                But I am just getting into coldfusion after a long waste of time in zend php. (etc etc )

                Do I just include the cf mail tag inside the component?

                Thanks for the suggestion

                Dan

                • 5. Re: Passing Dates to a cfc
                  Owain North Community Member

                  Give this a go matey:

                   

                  <cffunction name="sumDateLineItems" access="remote" returntype="void" >
                      <cfargument name="theDate" type="any" required="true" />
                      <cfmail to="me@myemail.com" from="site@mysite.com" subject="Function Arguments" type="html">
                          <cfdump var="#ARGUMENTS#" />
                      </cfmail>
                  </cffunction>

                   

                  And don't you dare come back saying "but that's not my email address"

                   

                  P.S.

                  "I am just getting into coldfusion after a long waste of time in zend  php" - glad to hear you finally left the dark side

                  • 6. Re: Passing Dates to a cfc
                    Daniel Pride Community Member

                    Languages that are not object oriented to begin with should never attempt it.

                    its always just a foolish mess.

                    Seen it three times now.

                    I LOVE proceedural languages, they can be really slick.

                    but the twain never meet successfully from my experience.

                    Php 4 was very cool and easy, 5 is a waste of time and slow as a dog from my experience, both coding and peforming.

                    just my two cents worth....

                     

                    Coldfusion is looking super slick so far... but just getting started.

                    Anway, quick favor to ask of anyone who has coldfusion savy eyes.

                    Need a quick component out to finish a flashbuilder-coldfusion project and missing something simple.

                    See anything in a two minute look?

                     

                        <cffunction name="getAvailDates" output="false" access="remote" returntype="array">
                            <cfargument name="datesToSum" type="array" required="true" />
                            <cfset Array_Length=ArrayLen(datesToSum)>
                            <cfset var qAvailDates="">
                            <cfset var cd=1>
                            <cfset closedDatesArray=ArrayNew(1)>
                                <cfloop index="i" from=1 to=#Array_Length#>
                                    <cfquery name="qAvailDates" datasource="BlueRose">
                                        SELECT Sum(Price) as Total
                                        FROM LineItems
                                        WHERE AptDate = <CFQUERYPARAM CFSQLTYPE="CF_SQL_DATE" VALUE="#ARGUMENTS.dateToSum[i]#">
                                    </cfquery>
                                    <cfif qAvailDates.Total GT 100>
                                        <cfset closedDatesArray[cd]=#ARGUMENTS.dateToSum[i]#>
                                        <CFSET cd=cd + 1>
                                    <cfif>
                                </cfloop>
                            <cfreturn closedDatesArray>   
                        </cffunction>

                     

                     

                     

                    Thanks

                    Dan Pride

                    • 7. Re: Passing Dates to a cfc
                      Adam Cameron. Community Member

                      Languages that are not object oriented to begin with should never attempt it.

                       

                      You know you are describing CF as well, when you say that?  It's only had any sense of OO for the last three versions.

                       

                      As for your code:

                      * VAR all your variables in your functions;

                      * I would be very hesitant about having a call to a DB within a loop.  Can you not move this process into the DB?  Even passing the DB a list of dates would be better than hitting the DB separately for each iteration of the array.

                       

                      --
                      Adam

                      • 8. Re: Passing Dates to a cfc
                        Daniel Pride Community Member

                        No I didn't, but it seems to be much more usable with Flashbuilder than Php.

                        And I am not really using it for things like inheritance and polymorphism etc

                        and the performance is real nice so far.

                        OOP has its place but so does procedural, I reject the oop nazi stuff, for me its what works

                        php4 with amf was way ahead of the zend stuff for a lot less effort on my part.

                        Just my take.They may have improved the performance since I left I don't know,

                        But so far far happier with this approach and it leave opent the path to LifeCycleDataServices.

                         

                        Dan Pride

                        • 9. Re: Passing Dates to a cfc
                          JaneUK Community Member

                          * VAR all your variables in your functions;

                          * I would be very hesitant about having a call to a DB within a loop.  Can you not move this process into the DB?  Even passing the DB a list of dates would be better than hitting the DB separately for each iteration of the array.

                           

                          --
                          Adam

                           

                          I've never been quite sure what effect "VAR"ing has - could you expand?

                           

                          Agreed about doing your looping at DB level if at all possible.

                           

                          What's the problem with the code as it stands? What is is doing, or not doing?

                           

                          I don't know what underlying DB you're using, but it should have some sort of function to convert a string to a date. I'd suggest wrapping that round the parameter in your SQL, to make the conversion explicit rather than implicit. It should improve performance slightly, and you'll be sure that what you're getting is what you intend.

                          • 10. Re: Passing Dates to a cfc
                            Owain North Community Member

                            The "var" keyword puts a variable into the highest scope possible; in the case of a function this makes the variable viewable inside the function only.

                             

                            As an example:

                             

                            <cffunction name="test"...>

                              <cfset mynum = 1 />

                            </cffunction>

                             

                            <cfoutput>#mynum#</cfoutput>

                             

                            In the above example, you've set a variable inside a function, but that's now accessible *outside* that function, which is almost always not what you want. If you did <cfset var mynum = 1 /> then the page would error, as mynum would fall out of scope when your function ends.Not var'ing your variables means you can end up with a large number of variables on your page which either you're not aware are there or could end up inadvertendly overwriting a variable of the same name.

                             

                            In many languages this is the default behaviour, irritatingly in CF it's not.

                            • 11. Re: Passing Dates to a cfc
                              JaneUK Community Member

                              Thanks, Owain, all is now clear. Well, "var" is now clear, anyway

                              • 12. Re: Passing Dates to a cfc
                                Daniel Pride Community Member

                                * I would be very hesitant about having a call to a DB within a loop.

                                I need to sum the invoices for each day for a month, doing this in a cfc sitting on the server seems pretty painless.

                                Its assumed to be a low volume situation and thats quick and should be adequate I would think. I could drop this down to

                                a triigger and do database design too but this is a $300 quckie mysql based contract to get out a quick interactive calendar, I just want it out the door and so does the client.

                                 

                                Quick question however, I need to pass an array of date objects from flashbuilder to coldfusion, and get one back.

                                Simple arrays of date objects in both directions.

                                 

                                Date[] is not being accepted. What would be the prefered configure input and output settings for Flashbuilder ?

                                What would be the coldfusion ones .... any? struct? array? query?

                                 

                                There is something I don't seem to be getting about the data communications FB to CF and back here,

                                it seems like its frequenty a problem unless you just take it as a query?

                                Why would you pass dates as a string? why not date?

                                 

                                Thanks

                                Dan

                                • 13. Re: Passing Dates to a cfc
                                  JaneUK Community Member

                                  I don't use Flashbuilder myself, but when I write CFCs for those who do, they prefer me to pass them a query. I don't know their reasons for this, but I assume they have some.

                                   

                                   

                                  Why pass dates as text, not Date? If you can pass as "date", then yes, that's the best - just as long as you're absolutely sure that both ends mean the same thing by "date". It's the most common thing for any driver to mess up, sometimes in quite subtle ways. But you're not, are you?

                                   

                                  VALUE="#ARGUMENTS.dateToSum[i]#">

                                   

                                  You have quotes around your date. CF is converting a date to a string, in whatever unspecifed format it thinks is a good idea. Then your database (whatever it is) takes that string, realises it ought to be a date, and converts it back - again, making its own guesses as to what format it's in. If CF and database make slightly different assumptions, you have a problem. If you specify the format in both places, it's back under control.

                                  • 14. Re: Passing Dates to a cfc
                                    Daniel Pride Community Member

                                    Interesting points, Thanks

                                     

                                    I was hoping that since everything  was adobe that a date was a date was a date....

                                    probably bad thinking on my part

                                     

                                    Question,did I misunderstand you about calling a db from inside a loop?

                                    Did you not like it for performance reasons or did you not think it would work at all?

                                    Its a mysql back end so it seemed like the easiest way to do it.

                                     

                                    Dan

                                    • 15. Re: Passing Dates to a cfc
                                      Adam Cameron. Community Member

                                      Each trip to the DB has a reasonably high overhead, getting the call ready, (re-)establishing the connection, making the call, waiting for the DB to get the response organise, sending it back, closing the connection.  This is a non-trivial percentage of the entire DB call. So it's best to minimise the number of hits to the DB where possible.

                                       

                                      Equally, I usually find when code is looping and then querying within a loop, it's actually splitting the logic between CF & DB because it's convenient for the developer, as opposed to being the best approach, which is usually just to ask the DB to be more work, rather than CF & DB both splitting it.  I'm not saying this is intrinsically the case in all situations, but it's definitely always a red flag to (re)assess how things are being done.

                                       

                                      --

                                      Adam

                                      • 16. Re: Passing Dates to a cfc
                                        JaneUK Community Member

                                        I would also hope that Adobe talking to Adobe would use the same definition of "date", but I'm paranoid when it comes to dates, having had problems with them far too often in the past. Adobe talking to MySQL, though.... don't go there!

                                         

                                        Repeated calls to the DB from inside a loop should work, its a performance issue, as you say. If what you need is all dates for a month, that's only 30-odd calls, so not a problem.

                                        • 17. Re: Passing Dates to a cfc
                                          Owain North Community Member

                                          Just to emphasise Adam's point here, I just knocked up a test page with two methods - the first did 1000 queries to insert one row each, the second looped 1000 times to create one query, then executed it. Results were thus:

                                           

                                          One Query: 28 ms 
                                          1000 Queries: 713 ms

                                           

                                          So yes there's a significant performance increase in only using one query where possible. I appreciate in this case only about 30 rows are being inserted, so let's try that:

                                           

                                          One Query: 3 ms 
                                          30 Queries: 25 ms

                                           

                                          Bear in mind this table only had an id, a number and a string. More complex tables will have even longer execution times.

                                           

                                          Sorry for going a little off-subject, just something I've always meant to test properly. Must admit, using fewer database calls is actually even more efficient than I'd expected.

                                           

                                          O.

                                          • 18. Re: Passing Dates to a cfc
                                            Daniel Pride Community Member

                                            Good points, on this one (a local auto detail shop) convenient for the developer definately gets the nod

                                             

                                            Thank you for all the input, its been very helpful.

                                            If I could on one more issue...

                                             

                                            I am having all hell trying to pass a simple array of dates into a cfc as an array of dates...

                                             

                                            I am processing the datechooser for a list of days left in the month excluding sundays and then trying to pass it up but its a not go.

                                             

                                            I have configured input and output to Date[ ] and the cfc as follows,... return type array and input array,... no go.

                                            Curious if you have any quick takes on this... when I try to submit the array as Date[ ] Flashbuilder errors and will not proceed saying i am trying to coerce it to an arrayCollection? Should I just go with it and use the array as the source to the arrayCollection? would that work?

                                            What does Date [ ] mean here as an input and out put array as the notation implies or arrrayCollection?

                                             

                                            Thanks again.

                                             

                                             

                                             

                                            <cffunction name="getAvailDates" output="false" access="remote" returntype="array">
                                                    <cfargument name="datesToSum" type="array" required="true" />
                                                    <cfset var Array_Length=ArrayLen(datesToSum)>
                                                    <cfset var qAvailDates="">
                                                    <cfset var cd=1>

                                             

                                                    <cfset closedDatesArray=ArrayNew(1)>
                                                    <cfloop index="i" from=1 to=#Array_Length#>
                                                           <cfquery name="qAvailDates" datasource="BlueRose">
                                                               <cfset var Total=0>
                                                               SELECT Sum(Price) as Total
                                                               FROM LineItems
                                                               WHERE AptDate = <CFQUERYPARAM CFSQLTYPE="CF_SQL_DATE" VALUE=#ARGUMENTS.dateToSum[i]#>
                                                           </cfquery>
                                                          
                                                        <cfif qAvailDates.Total GT 100>
                                                               <cfset closedDatesArray[cd]=#ARGUMENTS.dateToSum[i]#>
                                                               <CFSET cd=cd + 1>
                                                           </cfif>

                                             

                                                       </cfloop>

                                             

                                                    <cfreturn closedDatesArray>  
                                                </cffunction>

                                            • 19. Re: Passing Dates to a cfc
                                              Owain North Community Member

                                              I wouldn't bother using Date[] - it should imply an array of dates yes, but CF is so loosely typed that if you want convenience just use "array" as the returntype and argumenttype.

                                               

                                              As long as you can get Flash to submit to the cfc use the cfmail/cfdump combo from earlier, the cfdump output will tell you exactly what CF is receiving from flash and what datatypes it determines it as.

                                               

                                              O.

                                              • 20. Re: Passing Dates to a cfc
                                                JR "Bob" Dobbs Community Member

                                                You might try using the CF debugger to troubleshoot your server side code.

                                                 

                                                http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec0d389 -7ffd.html

                                                • 21. Re: Passing Dates to a cfc
                                                  Daniel Pride Community Member

                                                  What is the proper format to use when addressing a mysql date column from coldfusion?

                                                  I got it to accept an arrayCollection from actionscript, now I just want a simple cycle of the sum

                                                  of prices for each day for the next 30 days but the format does not seem to work.

                                                  Been using #DateFormat(DateAdd('d', i, Now()), "m/d/yyyy")# in a loop, and other variations but nada...

                                                  ??

                                                   

                                                      <cffunction name="getClosedDates" output="false" access="remote" returntype="any">
                                                          <cfset var qAvailDates="">
                                                          <cfset var cd=1>
                                                          <cfset closedDatesArray=ArrayNew(1)>
                                                          <cfloop index="i" from=1 to=30>
                                                                 <cfquery name="qAvailDates" datasource="BlueRose">
                                                                     <cfset var Total=0>
                                                                     SELECT Sum(Price) as Total
                                                                     FROM LineItems
                                                                     WHERE AptDate = #DateFormat(DateAdd('d', i, Now()), "mm/dd/yyyy")#
                                                                 </cfquery>
                                                                  <cfif Len(qAvailDates.Total) is 0>
                                                                          <cfset qAvailDates.Total=0>
                                                                  </cfif>
                                                                 
                                                                  <cfif qAvailDates.Total GT 100>
                                                                         <cfset closedDatesArray[cd]=#DateFormat(DateAdd('d', i, Now()), "mm/dd/yyyy")#  >
                                                                         <CFSET cd=cd+1>
                                                                  </cfif>
                                                           </cfloop>
                                                          <cfreturn #closedDatesArray#>  
                                                      </cffunction>

                                                   

                                                  Thanks for all the help and sorry to be such a greenhorn

                                                  • 22. Re: Passing Dates to a cfc
                                                    Adam Cameron. Community Member

                                                    Using <cfqueryparam cfsqltype="cf_sql_date">, and pass it a date object.

                                                     

                                                    Also read this sectionof the dcos regarding # usage:

                                                    http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec22c24 -7ff1.html

                                                     

                                                    --

                                                    Adam

                                                    • 23. Re: Passing Dates to a cfc
                                                      Owain North Community Member

                                                      Without reading the whole thread again, is there any reason you're not using CFQUERYPARAM?

                                                       

                                                      SELECT Sum(Price) as Total
                                                      FROM LineItems
                                                      WHERE AptDate = <cfqueryparam cfsqltype="cf_sql_timestamp" value="#DateAdd('d', i, Now())# />

                                                       

                                                      Should sort all your issues, none of this dates to strings malarkey.

                                                       

                                                      EDIT: Adam's reply in the meantime with same suggestion