> ## Documentation Index
> Fetch the complete documentation index at: https://doc.lucidworks.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom JavaScript Query Stage Examples

export const LwTemplate = ({title = "Key questions to get you started", icon = "sparkles", cta = "Powered by Agent Studio", linkHref = "https://lucidworks.com/demo/?utm_source=docs&utm_medium=referral&utm_campaign=docs_cta_ai"}) => {
  const [isLoaded, setIsLoaded] = useState(false);
  useEffect(() => {
    const timer = setTimeout(() => {
      setIsLoaded(true);
    }, 500);
    return () => clearTimeout(timer);
  }, []);
  return <div className="lw-template-container">
      <Card title={title} icon={icon}>
        {isLoaded && <span dangerouslySetInnerHTML={{
    __html: `<lw-template id="a029c1a9-28be-427e-b0e1-5d918920246a"></lw-template
            >`
  }} />}
        <Link href={linkHref} className="agent-studio-link text-left text-gray-600 gap-2 dark:text-gray-400 text-sm font-medium flex flex-row items-center hover:text-primary dark:hover:text-primary-light group-hover:text-primary group-hover:dark:text-primary-light">Powered by Lucidworks Agent Studio</Link>
      </Card>
    </div>;
};

[localhost link]: http://localhost:3000/docs/4/fusion-server/reference/pipeline-stages/query/example-custom-javascript-stages

[mintlify link]: https://doc.lucidworks.com/docs/4/fusion-server/reference/pipeline-stages/query/example-custom-javascript-stages

[old doc.lw link]: https://doc.lucidworks.com/fusion-server/4.2/ndokku

The following is a list of examples for reference when creating [custom JavaScript Query stages](/docs/4/fusion-server/concepts/querying/pipelines/custom-javascript-query-stages).

<LwTemplate />

## Add a parameter to the query request

```javascript wrap  theme={"dark"}
function(request,response , ctx, collection, solrServer, solrServerFactory) {
   request.addParam("foo", "bar");
}
```

## Add a parameter to the query response

This example contains a simple JavaScript function which copies information from the `ctx` (Context) object into the query response. Requirements:

* The `response` parameter cannot be used in query pipeline stages prior to the Solr query stage. This example assumes use in a later stage.
* The `response.initialEntity.appendStringList()` function only works if the query’s `wt` (writer type) parameter is set to json or xml, for example: `wt=json`.

```js wrap  theme={"dark"}
(function () {
    "use strict";

    var List = Java.type('java.util.List');

    function add_to_response(key, list) {
      if (list.length > 0) {
         response.initialEntity.appendStringList(key, Java.to(list, List));
      }
    }

    return function(request,response , ctx, collection, solrServer, solrServerFactory) {
       add_to_response('banners', ctx.getProperty('banners'));
       add_to_response('landing-pages', ctx.getProperty('redirects'));
    };
})();
```

## Java object interactions

The JavaScript engine used by Fusion is the Nashorn engine from Oracle.
See [The Nashorn Java API](https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/api.html) for details.

The Nashorn engine exposes the full Java Classpath to JavaScript. This means that Java objects can be instantiated and called from JavaScript. Objects returned by a call to a Java function will not be JavaScript objects. For example, calling `typeof(object)` will not give meaningful results. Instead, you can use JavaScript to discover the Java type of an object. Once you know the Java type of an object, you can refer to the [Fusion Pipeline Javadocs](/docs/5/fusion/dev-portal/pipeline-javadocs/overview) to learn more about the Java type and how to use Java Objects.

```js wrap  theme={"dark"}
/* globals Java, logger*/
(function () {
  "use strict";
  var Collection = Java.type("java.util.Collection")
  var isDebug = false
  function logIfDebug(m) { if (isDebug && m) logger.info(m, Array.prototype.slice.call(arguments).slice(1)); }

  /**
  * @return a boolean indicating whether or not a given object looks like a Java object
  */
  function isJavaType(obj) {
      return (obj && typeof obj.getClass === 'function' &&
            typeof obj.notify === 'function' &&
            typeof obj.hashCode === 'function');
  };
  function isJavaArray(obj) {
      return (obj && isJavaType(obj) && getTypeOf(obj).endsWith('[]'));
  };
  function isJavaCollection(collection) {
      return isJavaType(collection) && Collection['class'].isInstance(collection);
  };

  /**
  * Nashorn allows obj.length and obj['property'] and obj.property functionality
  * for some object types.  This helps discover that fact at runtime
  */
  function isArrayLike(obj) {
      return isJavaCollection(obj) || Array.isArray(obj) || isJavaArray(obj);
  };
/**
    * For Java objects, return the simplified version of their classname e.g. 'Format' for a java.text.Format
    * because Java naming conventions call for upper case in the first character.
    *
    * For JavaScript objects, the type will be a lower case string e.g. 'date' for a JavaScript Date.
    * Note: Nashorn uses java.lang.String objects instead of JavaScript string objects
    */
   function getTypeOf(obj, verbose) {
      'use strict';
      var typ = 'unknown';
      var isJava = isJavaType(obj);
      logIfDebug("UTIL getTypeOf:called with verbose: ",verbose);
      //test for java objects
      if (isJava && verbose) {
          typ = obj.getClass().getName();
          logIfDebug("UTIL getTypeOf:inverbose block, type:: ",typ);
      } else if (isJava) {
          typ = obj.getClass().getSimpleName();
      } else if (obj === null) {
          typ = 'null';
      } else if (typeof (obj) === typeof (undefined)) {
          typ = 'undefined';
      } else if (typeof (obj) === typeof (String())) {
          typ = 'string';
      } else if (Array.isArray(obj)) {
          typ = 'array';
      }
      else if (Object.prototype.toString.call(obj) === '[object Date]') {
          typ = 'date';
      } else {
          typ = obj ? typeof (obj) : typ;
      }
      return typ;
  };

  return function main(request, response, ctx, collection, solrServer, solrServerFactory) {
    //output info about the objects passed in
    logger.info("request object has type '{}'",getTypeOf(request,true))
    //note, response is only valued after the solr query stage
    logger.info("response object has type '{}'",getTypeOf(response,true))
    logger.info("ctx object has type '{}'",getTypeOf(ctx,true))
    logger.info("collection object has type '{}'",getTypeOf(collection,true))
    logger.info("solrServer object has type '{}'",getTypeOf(solrServer,true))
    logger.info("solrServerFactory object has type '{}'",getTypeOf(solrServerFactory,true))
  };
})();
```

## Manually add dependencies

To install dependencies manually, jar files must be placed in the `./apps/libs` folder. The jar file path must be included in `.apps/jetty/api/webapps/api-extra-classpath.txt` and `apps/jetty/connectors-classic/webapps/connectors-extra-classpath.txt`.

For example, to create script objects that access and reference Java types from Javascript use the `Java.type()` function:

```javascript wrap  theme={"dark"}
var TwitterFactory = Java.type("twitter4j.TwitterFactory");
var twitter = TwitterFactory.getSingleton();
```

For more information, see [Custom JavaScript Stages Variables and Parameters for Fusion 4.x.x](/docs/4/fusion-server/reference/query-ops/custom-javascript-stages-variables-and-parameters).
