Including multiple javascript dependencies

I'm working on a Apigee API Proxy where I have a javascript policy in which I want to include two additional javascript files.

Currently it will only include the first script and will return undefined on functions from the second script (same when I switch the order). Allthough the docs say "Include more than one JavaScript dependency resource with additional <IncludeURL> elements."

Is there a mistake here or is there something else at play?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" name="Script">
    <DisplayName>Script</DisplayName>
    <Properties/>
    <ResourceURL>jsc://mainscript.js</ResourceURL>
    <IncludeURL>jsc://additionalScript1.js</IncludeURL>
    <IncludeURL>jsc://additionalScript2.js</IncludeURL>
</Javascript>
Solved Solved
1 2 1,353
1 ACCEPTED SOLUTION

Something else at play, I think! What you are trying to do, should work. I use multiple includes regularly.

Your configuration looks fine. Sometimes it's difficult to diagnose just what is happening.

I understand that "return undefined on functions from the 2nd script" means... it's as if the 2nd script has not run at all.

Here's how I've diagnosed this in the past: try loading your scripts into jrunscript. jrunscript is a tool that is included with the JDK. If you have a developer workstation that has the JDK installed, you should be able to run it like so:

$JAVA_HOME/bin/jrunscript 

(flip the direction of the slashes for Windows machines)

Within the jrunscript "shell", you can load external modules, like this:

load('/Users/dino/dev/js/base64.js');
load('/Users/dino/dev/js/module2.js');

At that point, all of the functions defined in those modules will be available in the shell.

You should be able to use this to diagnose your modules. This is basically what Apigee Edge is doing when you specify your IncludeURL and Resource URL. In fact you can load one module at a time and verify on the terminal what is happening.

Even if your modules are loaded properly, it may be that they are structured in such a way as they do not export functions to the global namespace. You won't see any symptoms for that in jrunscript, or when configuring the JS step in Apigee Edge, beyond "my functions are undefined". The only way I know to diagnose this is to examine the source code for the JS modules to determine how the functions are defined.

For example, this code exports a function into the global namespace:

function f1(x) { return x * (x+1) ; } 

This code does not export a function into the global namespace:

(function () {
  function f1(x) {return x * (x+1); }
}());
 

The latter pattern - effectively it wraps code in an anonymous function, and then invokes that function, is a pattern that is used to specifically avoid inserting function definitions into the global namespace or scope. If your modules do this, or something like this, then the functions inside the anonymous function will not be available. So in this case it's a matter of expectations not matching the code.

Whether this applies to you is impossible to say, without looking at your code!

To diagnose further, maybe what you can do is totally simplify the situation, using two different but very simple IncludeURL modules, to see if you can get it working in the simple case. Then stepwise add complexity to see where things break down.

I'm happy to look further if you are willing to share the contents of your JS files.

View solution in original post

2 REPLIES 2

Something else at play, I think! What you are trying to do, should work. I use multiple includes regularly.

Your configuration looks fine. Sometimes it's difficult to diagnose just what is happening.

I understand that "return undefined on functions from the 2nd script" means... it's as if the 2nd script has not run at all.

Here's how I've diagnosed this in the past: try loading your scripts into jrunscript. jrunscript is a tool that is included with the JDK. If you have a developer workstation that has the JDK installed, you should be able to run it like so:

$JAVA_HOME/bin/jrunscript 

(flip the direction of the slashes for Windows machines)

Within the jrunscript "shell", you can load external modules, like this:

load('/Users/dino/dev/js/base64.js');
load('/Users/dino/dev/js/module2.js');

At that point, all of the functions defined in those modules will be available in the shell.

You should be able to use this to diagnose your modules. This is basically what Apigee Edge is doing when you specify your IncludeURL and Resource URL. In fact you can load one module at a time and verify on the terminal what is happening.

Even if your modules are loaded properly, it may be that they are structured in such a way as they do not export functions to the global namespace. You won't see any symptoms for that in jrunscript, or when configuring the JS step in Apigee Edge, beyond "my functions are undefined". The only way I know to diagnose this is to examine the source code for the JS modules to determine how the functions are defined.

For example, this code exports a function into the global namespace:

function f1(x) { return x * (x+1) ; } 

This code does not export a function into the global namespace:

(function () {
  function f1(x) {return x * (x+1); }
}());
 

The latter pattern - effectively it wraps code in an anonymous function, and then invokes that function, is a pattern that is used to specifically avoid inserting function definitions into the global namespace or scope. If your modules do this, or something like this, then the functions inside the anonymous function will not be available. So in this case it's a matter of expectations not matching the code.

Whether this applies to you is impossible to say, without looking at your code!

To diagnose further, maybe what you can do is totally simplify the situation, using two different but very simple IncludeURL modules, to see if you can get it working in the simple case. Then stepwise add complexity to see where things break down.

I'm happy to look further if you are willing to share the contents of your JS files.

Thanks @Dino for your elaborate answer.

I did not manage to find out why it wasn't working yesterday. Today it worked using the exact same files included in the exact same way.

// included file 1
var file1 = {};

file1.add = function(x) {
	return x+x;
};
// included file 2
var file2 = {};

file2.multiply = function(x) {
	return x*x;
};
// resource file
file1.add(1); // works
file2.multiply(2); // works

I switched to using a tool to bundle my files before adding them to apigee now so I don't have to bother with including anymore.