Float is getting converted to either int or string. But we need to pass it as float.

Hi @dchiesa1 ,

 

We're working on a response payload transformation. We're using javascript to do it as the response payload consists of lots of arrays. Here there's a field where we receive it as float and we need to pass a float to source systems.

 

But JS is somehow converting the float to int when decimal part contains only zeros. For example, 

if responsePayload.x = 5.009, our js is passing it as it is.

But if responsePayload.x = 5.00, our js is converting it into just 5(which is not acceptable). Is there any way to stop our float getting converted into into int when decimal part contains only zeros? Could someone please help?

 

Attaching a sample code for reference:

var payload = JSON.parse('{"name":"John", "age":30.000, "city":"New York"}');
var floaT = 0.00;

var page = payload.age.toFixed(5);
console.log(page)


let finalResponse={
name: payload.name,
age: payload.age,
hi: floaT
}
frs = JSON.stringify(finalResponse)
console.log(frs)

Response:

30.00100
{"name":"John","age":30,"hi":0}

 

P.S. We dont want to convert tis into string, for example "30.000". We just need to pass as float along the trailing zeros.

 

Thanks in advance!

Manoj T.

2 3 152
3 REPLIES 3

In JSON, as in JavaScript, and UNLIKE Java or C# etc, there are not distinct numeric types for representing floats and ints (cite). There is only Number.

5.00 is the same as 5. 

I think a system that is insisting on decimal points within JSON, is wrong.  It's unnecessarily rigid, or it's applying JSON incorrectly. 

If you really need Apigee to format numbers in a JSON payload with a minimum number of decimal digits, then you will probably need to resort to custom regex to manipulate the output of JSON.stringify(),  to make that happen. 

Or you could try with JSON.parse and a reviver function. The following is VERY HACKY, but works to emit numbers with decimal digits, when run in Rhino for simple (flat) objects. If you have something more complex , then I don't have any good suggestions for you. 


print("\n==================================");
var c = {
  keyid: "cc544724",
  meas: 17.1,
  expires: true,
  quality: 42,
  notbefore: "10s"
};

var json = JSON.stringify(c, null, 2);
print(json); // no decimal digits

var DESIRED_DECIMAL_PLACES = 3;
var modifiedString = "";

function reviver(key, value) {
  if (key) {
    if (modifiedString == "") {
      modifiedString = "{\n";
    } else {
      modifiedString += ",\n";
    }
    modifiedString += '  "' + key + '": ';
    var t = typeof value;
    if (t == "number") {
      // force decimal digits
      var output = value.toFixed(DESIRED_DECIMAL_PLACES);
      modifiedString += output;
    } else if (t == "boolean") {
      modifiedString += value;
    } else {
      modifiedString += '"' + value + '"';
    }
  }
  return value;
}
const unusedObject = JSON.parse(json, reviver);
print(modifiedString + "\n}"); // includes decimal digits

The output is: 

{
  "keyid": "cc544724",
  "meas": 17.100,
  "expires": true,
  "quality": 42.000,
  "notbefore": "10s"
}

 

Thanks for the reply, @dchiesa1 !

 

I'm afraid, we do not want to set the trailing zeros manually. We just want to pass what ever is coming from backend.

example:

var c = {
keyid: "cc544724",
meas: 17.100, //we're receiving this from backend. We need to pass it as such. We dont want to force add the trailing zeros.
expires: true,
quality: 42,
notbefore: "10s"
};

But I take it as "No. We can't pass the trailing zeros automatically." from your previous reply, "In JSON, as in JavaScript, and UNLIKE Java or C# etc, there are not distinct numeric types for representing floats and ints (cite). There is only Number.".

 

Thanks!

MJ

 

 

 

 


@the-mj wrote:

But if responsePayload.x = 5.00, our js is converting it into just 5(which is not acceptable).


 


@the-mj wrote:

17.100, //we're receiving this from backend. We need to pass it as such. We dont want to force add the trailing zeros.


 

I don't understand then.  You want Apigee to format the trailing zeros and also you DON'T want Apigee to format the trailing zeros. That sounds inconsistent to me!  I'm not sure that is a solvable problem, the way you've described it.

Also - why are you operating on the payload if you want it to be unchanged? If you want Apigee to relay the response it receives from the upstream, without changing it, then.... don't change it?  Why have a JavaScript at all?  

I think your problem is overconstrained. 

  • the client insisting on numeric format of numbers is json is ... broken. It's violating the JSON spec.
  • You want to manipulate the JSON payload, but you don't want Apigee to observe the JSON spec either (== you want Apigee to preserve the formatting of each field in the JSON payload)
  • and you require that Apigee not "force"? adding the zeros (== implementing the behavior that you say you want). 

?? I don't think I can help you further.