• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Custom number format function does not work to return 0's as decimals

Explorer ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

Hi

My custom number formatting function does not work. It was working fine when the site had a standard client server architecture. However, when we changed to using REST API with javascript and HTML5 the function works for most parts except cases when I need it to display 0's for decimals.

Basically, the function takes arguments a number and number of decimals and, returns the number rounded to the number of decimals passed. Below, I stripped the function to bare minimum, same as I was testing.

<cffunction name="dispCostPeriod" access="remote" returntype="string" output="false" hint="Displays costs for a given period to user">

     <cfargument name="in_decCost" type="numeric" required="yes" />

     <cfargument name="in_iRound" type="numeric" required="yes" />

  

     <cfset decRoundedNum = NumberFormat(in_decCost, "_." & RepeatString("9",in_iRound))>

     <cfreturn decRoundedNum />

</cffunction>

When I pass 55.00089 and 3, the function returns 55.001.

When I pass 55 or 55.000000 or 55.0000089 and 3, the function returns 55. And, I need 55.000.

I tried both to returntype "string" and "numeric", various masks like _.999, _.000, _.___.

I tried straight return NumberFormat(in_decCost,"_.000").

Nothing works.

I am using CF10 on Windows Server 2008.

Any help greatly appreciated.

Thanks,

Gena

Views

1.6K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Enthusiast , Jul 11, 2014 Jul 11, 2014

Can you explain how the data gets into the browser as a JSON formatted string?

Votes

Translate

Translate
Community Expert ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

What about the mask "00.000" or "99.999"? That is, using your syntax, "00." & RepeatString("0",in_iRound) or "99." & RepeatString("9",in_iRound).

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

"00.000" crashes the app. I tried "__.000". It returns " 55.000" as a string and further crashes the app. I need numeric value that will be evaluated further as a number.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

UPDATE: I called this very function from regular cfm page like that 

APPLICATION.cfc.calccostcoverage.dispCostPeriod(55,3)

And, it works as expected and returns 55.000.

Just wondering if it is something to do with how REST API returning values.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

You say you need a numeric value, but your function has string returntype. You should change the return type to numeric.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

I know I did, I tried different variations of the returntype, I mentioned this in my original post. The returned value is treated as numeric by javascript in the front end of the app and if it cant convert it to a number, the app crashes. So, even I left the returntype as a string, it is implicitly converted to a number later.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

Please show us how you actually call the function. For me, your function works fine (CF 10, Win 2008 server).

dispCostPeriod(55, 3) => 55.000

dispCostPeriod(0.00, 3) => 0.000

dispCostPeriod(55.0000089, 3) => 55.000

I can make those arguments strings or numbers, and same result.

Are you further transforming the number after converting it? How is JavaScript involved?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

Here is how I do function call


<cfset temp = APPLICATION.cfc.calccostcoverage.dispCostPeriod(55,3) />

For me it works fine too when I call it from cfm page, it does not work when call it within REST API.

I just do a call from URL:

http://10.200.5.2/rest/select/empselection


This is how it shows in the browser json dump:

"disp_price_tags": 55


I do not convert or transform it anywhere. The function works ok when I send any decimal number with decimals other than .00.


If I change the number to 55.1234, I get correct rounded value:

<cfset temp = APPLICATION.cfc.calccostcoverage.dispCostPeriod(55.1234,3) />

"disp_price_tags": 55.123

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

Ok, now I understand a bit better  Please show us the JavaScript code that calls the URL and passes the value. http://10.200.5.2/rest/v2_selections/empselection does not show anything that helps see the problem. Is JavaScript used, or not? Or are you using CFHTTP to the RESTful interface (as with other examples you've posted on various forums). I need to see the actual code that is doing the RESTful call and any associated script etc.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

Here is the javascript that does REST call

exports.fetchBenefits = function (action, empPlanId) {

        var promise = rest.GET({

            url: appConfig.restPrefix + 'selections/empselections?t=' + new Date().getTime()

        }, {

            effDate: (new Date()),

            empplan_id: empPlanId,

            loginaction: action

        });

        return promise;

    };

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

Put an alert() in so we can see the exact URL being called by rest.GET(). Put this line of code before the "var promise" line and paste the result back here so we can see it:

alert(appConfig.restPrefix + 'selections/empselections?t=' + new Date().getTime());

or

prompt("copy this", appConfig.restPrefix + 'selections/empselections?t=' + new Date().getTime()); // easier to cut and paste

When you put this code in, please test a few values, especially the ones that do not work, and paste the results here so we can see the URLs that do and do not work. This may yield a clue. Got to start somewhere

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

the value displayed is pretty much the same as it is a REST call

/rest/v2_selections/empselections?t=14050....

On that page I have few values displayed with this function but there is only one number with no decimals.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

I'm just trying to understand where it is that you pass the value 55. With RESTful calls you pass values in URL parameters or Form fields, so where are your values passed? Can you show us the full RESTful URL that contains all of the values you pass to your CFC? if your REST call is just /rest/v2_selections/empselections?t=14050 then where are the values, such as the number you want to convert? A HTTP trace would show the call too. Just curious.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

Number 55 is from a SQL query. Originally passed to the function in 55.00000 format. But, its all the same even if I do calculation on the number and pass it to the function.

The URL is below, i dont pass any values that need to be formatted

http://10.200.5.2/rest/v2_selections/empselections?t=1404932321302&effDate=Wed+Jul+09+2014+14%3A58%3...

I am just starting out with RESTful programming and not everything is clear but, I think this is something to do with REST passing values.

Interesting pattern, instead of using custom function I did straight NumberFormat() and DollarFormat() to the number.

<cfset structBenefits["disp_price_tags"] = NumberFormat(55.0000, "_.000")>

<cfset structBenefits["disp_price_tags_dollar"] = DollarFormat(55.0000)>

Result in browser json dump:

"disp_price_tags_dollar": "$55.00",

"disp_price_tags": 55

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

Is the "result in browser json dump" from the raw http response (like from the browser developer tools console) or the parsed JSON object from JavaScript code?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

from formatted or parsed json object within a browser window, i will try REST console tomorrow... office closing, have to leave now. But the actual page displays the number without decimals.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

I have been able to reproduce what you found. And more besides. I created the following component, using your function, and called it test.cfc:

<cfcomponent>

<cffunction name="dispCostPeriod" access="remote" returntype="numeric" output="false" hint="Displays costs for a given period to user">

    <cfargument name="in_decCost" type="numeric" required="yes" />

    <cfargument name="in_iRound" type="numeric" required="yes" />

 

    <cfset decRoundedNum = NumberFormat(in_decCost, "00." & RepeatString("0",in_iRound))>

    <cfreturn decRoundedNum />

</cffunction>

</cfcomponent>

Note that the return type is numeric. When I opened the following URLs in the browser, I got 55.0 in each case.

http://127.0.0.1:8500/workspace/cf11_proj/test.cfc?method=dispCostPeriod&in_decCost=55&in_iRound=3

http://127.0.0.1:8500/workspace/cf11_proj/test.cfc?method=dispCostPeriod&in_decCost=55.00&in_iRound=...

http://127.0.0.1:8500/workspace/cf11_proj/test.cfc?method=dispCostPeriod&in_decCost=55.000&in_iRound...

http://127.0.0.1:8500/workspace/cf11_proj/test.cfc?method=dispCostPeriod&in_decCost=55.0000000&in_iR...

If you add returnformat=json to the query-string, resulting in, for example,

http://127.0.0.1:8500/workspace/cf11_proj/test.cfc?method=dispCostPeriod&in_decCost=55.000&in_iRound...

each of the four URLs will return 55. Adding returnformat=plain instead to the URL fares just a bit better, producing 55.0 for all 4 URLs (possibly the default result we got earlier).

However, when you change the function's return type to string, each URL returns 55.000. This hints strongly at the function,

<cffunction name="dispCostPeriod" access="remote" returntype="string" output="false" hint="Displays costs for a given period to user" returnformat="plain">

     <cfargument name="in_decCost" type="numeric" required="yes" />

     <cfargument name="in_iRound" type="numeric" required="yes" />

     <cfset decRoundedNum = NumberFormat(in_decCost, "00." & RepeatString("0",in_iRound))>

     <cfreturn decRoundedNum />

</cffunction>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

Thanks, tribule. I appreciate the help.

I have to leave now, office is closing. I will try this tomorrow.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

Ok, hope to help. My gut is that the CFC is working, but the REST is somehow stripping your ".000" when "55.000" is returned.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jul 10, 2014 Jul 10, 2014

Copy link to clipboard

Copied

I agree, I think the REST value passing may be the issue here. The function seems to works fine when I call the CFC it with any variation of 55. It always returns 55.000 in all cases. That's with returntype="string" as in your original function posted above. The returnformat="plain" does not affect things for me, as far as I can see.

Btw, In every example you've given, you still have not shown us the exact URL call that includes the value "55" You say "Number 55 is from a SQL query" but where is "55" passed to the CFC? Can you do a HTTP trace (F12/developer tools etc) of an entire session and paste it here please so we can all see the exact network communications going on? Without seeing what URLs are being called, it's really hard to rule out other issues that may be affecting things.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 11, 2014 Jul 11, 2014

Copy link to clipboard

Copied

Thats what I think, REST is stripping of 0's from the number.

I tried returntype="plain" and it had no effect.

I tried your line <cfset decRoundedNum = NumberFormat(in_decCost, "00." (mask "0." works ok) & RepeatString("0",in_iRound))> and it crashed the app. The front expects number and having "00." mask forces the number to explicitly convert to string by adding extra space in front, data returns in this format:

"disp_price_tags": " 55.000"

As for network traffic, this is exactly the link I copied from the console when I click the button leading to the page that displays numbers in question:

http://10.200.5.2/rest/v2_selections/empselections?t=1405095651942&effDate=Fri+Jul+11+2014+12%3A20%3...

Below, is the REST component with relevant lines. May be here something that may raise a quesion.

<cfcomponent rest="true" restpath="empselections">

  <cffunction name="getSelections" access="remote" produces="application/json" returnType="struct" httpmethod="GET">

      <cfargument name="effDate" type="any" default="#Now()#" restargsource="query" required="no" />

      <cfargument name="empplan_id" type="numeric" default="0" restargsource="query" required="no" />

      <cfargument name="loginaction" type="string" default="live-events" restargsource="query" required="no" />

      ........

       <cfset structEmpselections["empselections"] = getCurrEmpBenefits(empplan_id = #VARIABLES.iEmpplanID#) />

       ........

  </cffunction>

  <cffunction name="getCurrEmpBenefits" access="private" returntype="array">

      <cfargument name="empplan_id" type="numeric" required="yes">

       ......

       <cfstoredproc procedure="qGetSelections" datasource="#REQUEST.dsn#" username="#REQUEST.dbusername#" password="#REQUEST.dbpassword#">

            <cfprocparam cfsqltype="CF_SQL_INTEGER" value="#ARGUMENTS.empplan_id#" dbvarname="@iEmpplanID" type="IN">tusID" type="IN">

            <cfprocresult name="getCurrBenefits">

       </cfstoredproc>

       ......

       <cfloop query="getCurrBenefits">

               ...........

            <cfset structOptionDetails = cnf_u_insempnext(qUSelections = APPLICATION.cfc.format.QueryToStruct(#getCurrBenefits#, #getCurrBenefits.CurrentRow#))>

            <cfset structOption["option_details"] = structOptionDetails />

            .............

       </cfloop>

       ........

       <cfreturn arrGroupBenefits />

  </cffunction>

<cffunction name="cnf_u_insempnext" access="private" returntype="struct">

    <cfargument name="qUSelections" required="yes" type="struct">

       .......

       <cfset structEmpUBenefits["disp_price_tags"] = APPLICATION.cfc.calccostcoverage.dispCostPeriod(structEmpUBenefits["price_tags"]), iDispCostPeriodID, iFlexRound)>

       ......

       <cfreturn structEmpUBenefits />

  </cffunction>

</cfcomponent>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 11, 2014 Jul 11, 2014

Copy link to clipboard

Copied

<cfset structEmpUBenefits["disp_price_tags"] = APPLICATION.cfc.calccostcoverage.dispCostPeriod(structEmpUBenefits["price_tags"]), iDispCostPeriodID, iFlexRound)>

That line has one ) symbol too many. In any case, it appears to call the dispCostPeriod function with 3 parameters instead of 2.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 11, 2014 Jul 11, 2014

Copy link to clipboard

Copied

I removed one parameter to simplify this. That just a flag to divide the number by 12 (monthly). In most cases its 1 so, no division is done in this case.

As for the bracket, was trying to format display ... couple of undo, redo in editor... anyway, just an accident. Syntax like that, crashes the app.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 11, 2014 Jul 11, 2014

Copy link to clipboard

Copied

As for network traffic, this is exactly the link I copied from the console when I click the button leading to the page that displays numbers in question:

http://10.200.5.2/rest/v2_selections/empselections?t=1405095651942&effDate=Fri+Jul+11+2014 +12%3A20%...

Any other traffic info can be useful?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jul 11, 2014 Jul 11, 2014

Copy link to clipboard

Copied

Hmm, ok it seems the empplan_id value is used to get the value 55 by passing it to a query. Is that correct?

This line is the only thing I can see that needs further scrutiny:

<cfset structEmpUBenefits["disp_price_tags"] = APPLICATION.cfc.calccostcoverage.dispCostPeriod(structEmpUBenefits["price_tags"], iDispCostPeriodID, iFlexRound)>

Can you <cfdump> these values after the above statement, and paste them back here so we can look at the results:

<cfdump var="#structEmpUBenefits['disp_price_tags']#">

<cfdump var="#structEmpUBenefits['price_tags']#">

<cfdump var="#structEmpUBenefits#">

<cfdump var="#iDispCostPeriodID#">

<cfdump var="#iFlexRound#">

Can you hard code 55 in to the call to see if it works, like this:

<cfset structEmpUBenefits["disp_price_tags"] = APPLICATION.cfc.calccostcoverage.dispCostPeriod(55, iDispCostPeriodID, iFlexRound)>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation