Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

Apigee X JavaScript Math Object

Hi @kurtkanaskie 

If there was a thread already, please do point me there for the query. Does the JavaScript Math Object support Long, type. While executing the proxy I see the following error:

{
    "fault": {
        "faultstring": "Execution of JS-CalculateExpiryTime failed with error: Javascript runtime error: \"TypeError: Cannot find function Long in object [object Math]. (calculateTimeStamp.js:5)\"",
        "detail": {
            "errorcode": "steps.javascript.ScriptExecutionFailed"
        }
    }
}
I am trying to achieve something like this :

 

var currentTime = Math.floor(+new Date()); // the current time in milliseconds
var issuedAtTimeSeconds = Long.valueOf(currentTime/1000);

 

 Thanks,
Debjit
Solved Solved
4 4 402
1 ACCEPTED SOLUTION

Thanks @dchiesa1 , I used the Math round function to achieve this and was able to get the value rounded off, I do have one last question, I am trying this 

 

var currentTimeStamp = context.getVariable("system.timestamp");
print("The current time is "+currentTimeStamp);
var issuedAtTime = Math.round(currentTimeStamp/1000);
print("The issued time is "+issuedAtTime);
var timeToExpire = 300;
var expirationTime = issuedAtTime+timeToExpire;
print("The expiration time is "+expirationTime);
var expTime = context.setVariable("expTime", context.getVariable("expirationTime"));
print("The exp time is "+expTime);

 

I printed the values to check if its getting values correctly to each variable, but the value for expTime is evaluating to undefined, I am seeing the GET to expirationTime is empty which I am sure is cause for the value of expTime to be showing as undefined, but am unable to figure out the issue. Please let me know if am missing out something, excerpt from the trace below:

The current time is 1719255765674 The issued time is 1719255766 The expiration time is 1719256066 The exp time is undefined

expTimeValue.PNG

I intend to use the value of expTime downstream within the proxy, by referencing to this variable.

Thanks,

Debjit

View solution in original post

4 REPLIES 4

I think Long.valueOf() might be Java syntax. Not JS.

Maybe what you want is

 

var currentTime = new Date().valueOf(); // the current time in milliseconds
var issuedAtTimeSeconds = Math.round(currentTime / 1000);  // a Number

 

or alternatively

 

var currentTime = new Date().valueOf(); // the current time in milliseconds
var issuedAtTimeSeconds = (currentTime / 1000).toFixed(0); // a String

 

Thanks @dchiesa1 , I used the Math round function to achieve this and was able to get the value rounded off, I do have one last question, I am trying this 

 

var currentTimeStamp = context.getVariable("system.timestamp");
print("The current time is "+currentTimeStamp);
var issuedAtTime = Math.round(currentTimeStamp/1000);
print("The issued time is "+issuedAtTime);
var timeToExpire = 300;
var expirationTime = issuedAtTime+timeToExpire;
print("The expiration time is "+expirationTime);
var expTime = context.setVariable("expTime", context.getVariable("expirationTime"));
print("The exp time is "+expTime);

 

I printed the values to check if its getting values correctly to each variable, but the value for expTime is evaluating to undefined, I am seeing the GET to expirationTime is empty which I am sure is cause for the value of expTime to be showing as undefined, but am unable to figure out the issue. Please let me know if am missing out something, excerpt from the trace below:

The current time is 1719255765674 The issued time is 1719255766 The expiration time is 1719256066 The exp time is undefined

expTimeValue.PNG

I intend to use the value of expTime downstream within the proxy, by referencing to this variable.

Thanks,

Debjit

Thank you @dchiesa1 for this explanation and I have tried your steps outlined and checked in the Trace, the values are being assigned.

I think you want

 

var timeToExpire = 300;
var expirationTime = issuedAtTime+timeToExpire;
print("The expiration time is "+expirationTime);
// var expTime = context.setVariable("expTime", context.getVariable("expirationTime")); NO
context.setVariable("expTime", expirationTime);

// The following is not really necessary, for funcitonal purposes. 
// It is interesting only for diagnostics I guess.
var expTime = context.getVariable("expTime");
print("The exp time is "+expTime);

 

When you are discussing Apigee JS callouts, there are two "scopes" or "contexts" in which variables exists.

One is the "message context" in the API Proxy. All the Apigee policy types work by reading and setting context variables, sometimes called "flow variables". For example if you use OAuthV2/VerifyAccessToken and it succeeds, the policy sets a number of context variables with information about the token, the api product, the expiry of the token, and so on .

Subsequent policies can "read" these variables by referencing them in message templates or ref='' attributes in the policy configuration. Or, you can refer to these context variables in Condition elements inside your Apigee proxyendpoint or targetendpoint.

a JavaScript step has a distinct "scope" for variables during its execution. We can declare and initialize variables with the var statement, and you can update variables with simple JS assignment syntax. Eg

 

// initialize a variabled named myVariable
var myVariable = 7;
// update the value of myVariable
myVariable = myVariable * 12;

 

The variables inside JS and the variables inside the message context are in different scopes. Within a JS module, you can "read" a context variable with context.getVariable() and you can write a contextVariable with context.setVariable().

 

// 1. get a variable from message context and set a local JS variable with its value
var jsVar = context.getVariable('request.verb');

// jsVar will now hold one of: 'GET', 'POST', 'DELETE', etc.
// depending on the request that is being served.

// 2. set a variable into message context with a value known in local js context.
var localJsValue = (new Date()).valueOf() / 1000;   // epoch seconds
context.setVariable('calculated_now', localJsValue);

// subsequent policies or Condition elements in the Apigee proxy can refer to 
// a variable named 'calculated_now'

 

in your case the expirationTime variable is known in JS scope. It seems like you want to set a context variable holding the same value. So

 

// Set the value of a context variable named expTime to 
// the current value of the variable in JS scope, named expirationTime. 
context.setVariable('expTime', expirationTime);

 

For the logic you used,

 

var expTime = context.setVariable("expTime", context.getVariable("expirationTime")); // wrong

 

...what you are doing with context.getVariable is reading the variable expirationTime from message context. It has not been previously set in message context. (Though, coincidentally in your JS there is a local JS variable with the same name.) When this JS executes, it causes a GET variable action to appear in the debugsession - you can see that line in your trace snapshot. And you can see the value is empty - because there is no such variable in the message context, the call to context.getVariable() returns an empty value. Then you use context.setVariable to set a context variable named expTime to the same thing you just retrieved (which is nothing). So expTime in the message context gets the value null, or empty.

Finally you are setting the local JS variable named expTime to the output of the context.setVariable() call, which I think is void (aka undefined). And remember the expTime that is known in the JS execution scope is different that the similarly named variable in the message context.

So that is why you see undefined in your print statement output.