CartJS API to add multiple item to cart and submit order

Arun Chauhan
Giga Contributor

I have a requirement where I need to create a single Service Request ticket with multiple RITMs. I am trying to use the CartJS API i.e. sn_sc.CartJS. I have defined an API endpoint like below:

https://devxxxx.service-now.com/api/x_123589_myscope/my_catalog_api/create_ticket

and I am sending below body in the REST request:

{

    "items":[

          {

                "sys_id":"b5c3d4280fd112406f23ba8ce1050e1a",

                "variables":{

                      "requested_for":"ece090564fb30300439c30318110c7e0"

                  }

          },

          {

          "sys_id": "9af59b9a4fc01300439c30318110c791"

          }

    ]

}

Below is my code in the Scripted REST resource:

(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {

var request_body = request.body.nextEntry();

var requestedItems = request_body.items || [];

var cartId = gs.generateGUID();

gs.info("Requested Items Length : " + requestedItems.length + " GUID : "+ cartId);

var cart = new sn_sc.CartJS("cart_" + cartId);

for(i=0; i<requestedItems.length; i++) {

      var itemDetails = requestedItems[i];

      var itemId = itemDetails.sys_id;

      if(!itemId)

            throw new sn_ws_err.BadRequestError('Item id is required');

      itemDetails.sysparm_id = itemDetails.sys_id;

      itemDetails.sysparm_quantity = '' + (itemDetails.sysparm_quantity || '1');

      if (!itemDetails.variables) {

              itemDetails.variables = {};

      }

      gs.info("Item Details : " + itemDetails);

      cart.addToCart(itemDetails);

}

var cartItems = cart.getCartItems();

      gs.info("CartItems : "+ cartItems);

var checkoutInfo = cart.checkoutCart();

cart.empty();

      gs.info(checkoutInfo);

})(request, response);

I am passing array of Catalog items with sys_id in the request. I am parsing the request in the script and creating a unique cart using random GUID. Then I am using addToCart method to add each item to cart and finally using cart.checkoutCart to create the REQ and RITMs.

But this results in creation of an empty REQ with no RITM. Also in logs I can see below warning:

java.lang.NullPointerException

Caused by error in sys_ws_operation.e2648fde4f801300439c30318110c7c8.operation_script at line 1

com.glideapp.servicecatalog.CartRecord.checkout(CartRecord.java:1162)

com.glideapp.servicecatalog.CartRecord.checkoutCart(CartRecord.java:1148)

com.glideapp.servicecatalog.scoped.api.CartJS.jsFunction_checkoutCart(CartJS.java:578)

sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

java.lang.reflect.Method.invoke(Method.java:498)

and below error:

java.lang.NullPointerException: com.glide.rest.domain.ServiceException: java.lang.NullPointerException: com.glide.rest.service.custom.CustomServiceExceptionResolver.throwServiceException(CustomServiceExceptionResolver.java:91)

com.glide.rest.service.custom.CustomServiceExceptionResolver.throwServiceException(CustomServiceExceptionResolver.java:81)

com.glide.rest.service.custom.CustomServiceExceptionResolver.resolveForException(CustomServiceExceptionResolver.java:39)

com.glide.rest.service.custom.CustomServiceResultHandler.handle(CustomServiceResultHandler.java:23)

com.glide.rest.service.custom.CustomService.execute(CustomService.java:83)

com.glide.rest.handler.impl.ServiceHandlerImpl.invokeService(ServiceHandlerImpl.java:36)

com.glide.rest.processors.RESTAPIProcessor.process(RESTAPIProcessor.java:271)

com.glide.processors.AProcessor.runProcessor(AProcessor.java:483)

com.glide.processors.AProcessor.processTransaction(AProcessor.java:205)

com.glide.processors.ProcessorRegistry.process0(ProcessorRegistry.java:178)

com.glide.processors.ProcessorRegistry.process(ProcessorRegistry.java:167)

com.glide.ui.GlideServletTransaction.process(GlideServletTransaction.java:31)

com.glide.sys.Transaction.run(Transaction.java:2038)

java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)

java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)

java.lang.Thread.run(Thread.java:748)

Any help?

7 REPLIES 7

larstange
Mega Sage

Hi



You items json is not correct. It should look like this



{


        'sysparm_id': item_id,


        'sysparm_quantity': item_quantity,


        'variables':{


                  'var_name': 'var_value',


                  ...


        }


}


Hi Lars,



Thanks for the reply. I have it in my script code. Please see below:



itemDetails.sysparm_id = itemDetails.sys_id;


Ahh - yes I can see that. Well than I can't see any errors as such.



But can you try and send a "clean" json where you do not have any "sys_id" objects in it and conform strictly to the specification from servicenow?


Update:



To get the root cause of the issue, I have created a script with below code:




var cartId = gs.generateGUID();


// test code start


var item =


      {


          'sysparm_id': 'b5c3d4280fd112406f23ba8ce1050e1a',


          'sysparm_quantity': '1',


          'variables':


          {


              'requested_for': 'ece090564fb30300439c30318110c7e0'


          }


      };


var cart = new sn_sc.CartJS(cartId);


cart.addToCart(item);


cart.checkoutCart();




The above script only creates the REQ with no RITM. But if I remove the argument while creating cart i.e. cartId from new sn_sc.CartJS, it works just fine. I think CartJS can accept a unique id while creating the cart as per mentioned in this doc. I am not able to understand the issue here.



Note: I have created this script in my scoped application.