Search code examples
arrayskaratejsonpath

Karate - Unable to get a list of 2 lists elements from a response


I'm struggling with this for several days. This is the answer I get (with anonymous data). I want to retrieve the first "channel_definitions[2]" by checking this data :

When the channel_definitions is an array of 2 then :

  • the name is "Maddy's life ***********" for the mode "THE FIRST MODE" (please note there is a " ' " in the name)
  • the name is " *********** computer" for the mode "THE SECOND MODE" [ { "id": "82", "channel_definitions": [ { "id": "8200", "mode": "THE FIRST MODE", "types": [ "VALUE", "HOME" ], "interactive": true, "name": "Maddy's life ***********", }, { "id": "8201", "mode": "THE SECOND MODE", "types": [ "BOOKING", "CREDIT" ], "name": " *********** computer" } ] },
    { "id": "10002", "channel_definitions": [ { "id": "1000201", "mode": "THE SECOND MODE", "types": [ "BOOKING", "CREDIT" ], "name": " *********** computer" } ] }, { "id": "88", "channel_definitions": [ { "id": "8800", "mode": "THE FIRST MODE", "types": [ "BOOKING", "VALUE", "HOME", "CREDIT" ], "name": "piano §§§§§§§§§§" } ] }, { "id": "149", "channel_definitions": [ { "id": "14900", "mode": "THE FIRST MODE", "types": [ "VALUE" ], "name": "+++++ paraglading ++++++++++++++" } ] }, ]

I have done the 2 others parts.

I tried everything I thought can works and I read on the Internet but not the correct one. For instance deals with these ideas

  • def listOfChannelDef = karate.jsonPath(response, "$..channel_definitions== '#[2]'")
  • def listOfChannelDef = karate.jsonPath(response, "$..channel_definitions[2]")

Please if you know how to do it or has any idea of how to do it let me know.

Alicya


Solution

  • I suggest not using JsonPath and instead - using simple JS functions (built-in to arrays) to get what you want.

    For example, this is the best guess of your question:

    * def found = response.find(x => x.channel_definitions.length == 2 && x.channel_definitions[0].mode == 'THE FIRST MODE' && x.channel_definitions[0].name == "Maddy's life ***********")
    

    If you want to make it easier to read:

    * def fun = 
    """
    function(x) {
      return x.channel_definitions.length == 2 
        && x.channel_definitions[0].mode == 'THE FIRST MODE' 
        && x.channel_definitions[0].name == "Maddy's life ***********";
    }
    """
    * def found = response.find(fun)
    

    All JSON arrays in Karate are "true" JS arrays, so the functions find(), map() and filter() can be applied very effectively to do JSON transforms.

    For example, if you just want to "collect" all channel_definitions that have a length of 2 as a first step, and then do some checks. And note how you can escape the single-quote or you could have used double-quotes also like shown above.

    * def filtered = response.filter(x => x.channel_definitions.length == 2)
    * def names = filtered[0].channel_definitions.map(x => x.name)
    * match names == ['Maddy\'s life ***********', ' *********** computer']