Apigee Variable in a JavaScript

What are you doing:

I am attempting to fill in defaulted Apigee variables within a client request in the event the client does not provide them. If the client does provide them, then I will use what the client provides over the default. The JS policy will execute in a Flow Condition:

<Step>
   <Condition>
       (request.queryparam.paramA.values = "[]")
   </Condition>
       <Name>JS-setDefaultQueryParam</Name>
</Step>

Essentially, if the client request.queryparam.paramA.values is equal to null, then run the JS-setDefaultQueryParam policy. <-- This executes as expected.

I will the form the backend request in an AssignMessage policy.

To do this I am using a JavaScript policy:

Starting Simple with 1 parameter and will expand this to 6 parameters when finished

var jspparamA = context.getVariable("request.queryparam.paramA.value");

if (jspparamA === [] || jspparamA === "") then;
 
    context.getVariable('provided.paramA');

    context.setVariable(jsparamA, 'provided.paramA');

else if (jsparamA != [] || jsparamA != "") then,

    context.setVariable(jsparamA, 'request.queryparam.paramA.value');

"request.queryparam.paramA.value" is what the client is sending. I am creating a variable "jsparamA" and if "jsparamA" is equal to null or undefined, then look to Apigee and read in defaulted "provided.paramA" which is being set in the proxy PreFlow.

What are you expecting to see:

Once the JavaScript executes, I should be able to call "jsparamA" variable within my AssignMessage and the value populates, but it is not working as expected. I have confirmed that all my default variables are getting read into Apigee poperly and within Apigee I can call them, but I am using JavaScript for logic to determine if the client has sent a parameter or has left it blank. Once determined as blank, then run the JavaScript and populate it with default otherwise use what the client sends in the initial request. All of this functionality happens within the proxy request.

Any help with this is appreciated I am not new to using Apigee, but am new to using JavaScript within Apigee.

Solved Solved
1 7 5,653
1 ACCEPTED SOLUTION

I was finally able to get this working. In the event this will help someone else having this problem below is the code I used:

var jsparamA

   context.setVariable("jsparamA", context.getVariable("request.queryparam.paramA"))
if (context.getVariable("jsparamA") === [] || context.getVariable('jsparamA') === "") { 
    context.setVariable("jsparamA", context.getVariable("provided.paramA"));
    print(jsparamA);
           }
else if (context.getVariable("jsparamA") !== [] || context.getVariable("jsparamA") !== "")
     context.setVariable("jsparamA", context.getVariable("request.queryparam.paramA"));
     print(jsparamA);

The above code uses the Apigee defined variable "request.queryparam.paramA" and sets it a new variable "jsparamA" (known only in the local script). After that it will then determine if "jsparamA" is equal to null or undefined. If "jsparamA" is null or undefined it will then assign it the value of Apigee defined variable "provided.paramA". However, if "jsparamA" is not null or undefined, then it will set the value of "jsparamA" to the Apigee defined variable of "request.queryparam.paramA".

Doing this allows us to default a value if the client neglects to send a value in with the request. if the client does provide a value with the incoming request, then Apigee will use that value instead.

Thanks to everyone for all the help with this one!

View solution in original post

7 REPLIES 7

Can you please describe at which step you have an issue?

Additionally, enclose jsparamA in quotes when you do context.setvariable call. You can then access the variable in a subsequent assignmessage policy.

The issue I am having right now is the javascript is not reading in the variables defined in Apigee. I have confirmed the variables are cached via and Extract Variable policy, but I am not able to call them inside the JavaScript so they can be evaluated. Adding quotes around them, simply define the variable as the literal string rather than the Apigee variable value. Any thoughts on what I am doing wrong here?

Can you pls attach your trace?

Since this is a public forum I am not able to put the entire trace on here, but I did extrapolate the area where the literal string value is being placed into my formatted AssignMessage from the TraceLogs:

<RequestMessage>
            <Content>
            {   
                "customerId": "",
                "branchId": "",
                "contractId": "",
                "shipWhseId": "",
                "products": [
            {
                    "productId": "request.queryparam.productId.value",
                    "quantity": ""
                }
            ]
         }
        </Content>
            <Headers>
                <Header name="cache-control">no-cache</Header>
                <Header name="Content-Type">application/json</Header>
            </Headers>
            <URI>/</URI>
            <Verb>POST</Verb>
        </RequestMessage>
<br>

Instead of the value for "request.queryparam.productId.value" being placed into the AssignMessage I am simply getting the literal string value placed into the AssignMessage. This would not be happening if the JavaScript was reading in the already defined variables.

Below are the client request variables shown in the trace:

known.productId
known.shipWhseId 986
known.customerId 27078
known.quantity 1<br>

As you can see I intentionally left "known.productId" empty so the JavaScript policy could execute and supply it with the default variables you will see below:

Below are the default variables shown in the Trace:

provided.customerId 27078
provided.productId 419280
provided.shipWhseId 986
provided.quantity 1<br>

In this example "provided.produtId" equals "419280" and I am calling it in the JavaScript, but instead of reading in the Apigee existing variable I am getting the literal string value of what I put into the script in quotes "request.queryparam.productId.value" when it should be "419280"

I am not very experienced with JavaScript but the script itself is not throwing any errors nor does Apigee see any formatting issues with it. This must be something I am missing when attempting to have the script read in the variables:

var jsproductId = context.getVariable("request.queryparam.productId.value");
if (jsproductId === [] || jsproductId === "") { 
    context.getVariable('provided.productId');
    context.setVariable("jsproductId", 'provided.productId');
           }
else context.getVariable("request.queryparam.productId.value");
     context.setVariable("jsproductId", "request.queryparam.productId.value");
<br>

I updated the script to a simple "if/esle" statement and surrounded the Apigee defined variables in quotes per your suggestion, but as I mentioned it is simply just reading the literal string rather than pulling the Apigee defined variables. Lastly, all of these variables are being set in the Proxy PreFlow.

Any thoughts?

sidd-harth
Participant V

Maybe try this JS Code, it is a bit confusing, but I guess the logic works. You can replace y with an meaningful value,

var y = context.getVariable("request.queryparam.paramA.value");

if (y === [] || y === "") then;
 
  var x =  context.getVariable('provided.paramA');

    context.setVariable("y",x);

else if (y != [] || y != "") then,

    context.setVariable("y", y);

Just some background info:

  1. Variables set in a JS callout are scoped to the script. If you want to set a variable in the proxy context, that's a different scope, and for that you need to use context.setVariable(). The name you specify for the context variable, the first argument to that call, must be a string.
  2. you can retrieve queryparams from within a JS callout as context.getVariable('request.queryparam.NAME') , where NAME is replaced with the name of the query param (paramA in your case). You are using request.queryparam.NAME.value, and I think that's incorrect. Here is the relevant doc: link.

Just trying to infer your intent, this is what I came up with. See if this helps.

var paramA = context.getVariable("request.queryparam.paramA");
// paramA is known only within this local JS
if (paramA != null) {
  // set some variables in the proxy context.
  context.setVariable('provided.paramA', paramA);
  context.setVariable('effective.paramA', paramA);
}
else {
  context.setVariable('notice', 'there was no paramA detected within JS');
  // set some variables in the proxy context
  context.setVariable('provided.paramA', paramA);
  context.setVariable('effective.paramA', properties.default_paramA);
}

Quick note: that "properties.default_paramA" is a mechanism for reading a Property that is set in the JS callout configuration like this:

<Javascript name='JS-DetectQueryParam' timeLimit='200' >
  <Properties>
    <!-- the following is available in JS as properties.default_paramA -->
    <Property name='default_paramA'>default-value-for-paramA</Property>
  </Properties>
  <ResourceURL>jsc://detectQueryParam.js</ResourceURL>
</Javascript>

What I see when I invoke that script as a JS callout:

inbound query string context variables read context variables written
?paramA=2 request.queryparam.paramA = 2 provided.paramA = 2
effective.paramA = 2
(none)

request.queryparam.paramA = null

notice = there was no paramA detected within JS
provided.paramA = null
effective.paramA = default-value-for-paramA

Attached please find a working proxy that illustrates this. Deploy it and trace it, then invoke it as:

curl -i https://$ORG-$ENV.apigee.net/js-detect-queryparams?paramA=value

apiproxy-js-detect-queryparams.zip

I was finally able to get this working. In the event this will help someone else having this problem below is the code I used:

var jsparamA

   context.setVariable("jsparamA", context.getVariable("request.queryparam.paramA"))
if (context.getVariable("jsparamA") === [] || context.getVariable('jsparamA') === "") { 
    context.setVariable("jsparamA", context.getVariable("provided.paramA"));
    print(jsparamA);
           }
else if (context.getVariable("jsparamA") !== [] || context.getVariable("jsparamA") !== "")
     context.setVariable("jsparamA", context.getVariable("request.queryparam.paramA"));
     print(jsparamA);

The above code uses the Apigee defined variable "request.queryparam.paramA" and sets it a new variable "jsparamA" (known only in the local script). After that it will then determine if "jsparamA" is equal to null or undefined. If "jsparamA" is null or undefined it will then assign it the value of Apigee defined variable "provided.paramA". However, if "jsparamA" is not null or undefined, then it will set the value of "jsparamA" to the Apigee defined variable of "request.queryparam.paramA".

Doing this allows us to default a value if the client neglects to send a value in with the request. if the client does provide a value with the incoming request, then Apigee will use that value instead.

Thanks to everyone for all the help with this one!