Setting a value into a json using jsonPath in karate - json

I have the below Json File(Test.json) read into a variable in karate
TestInput.json:
{
"firstName": "John",
"lastName" : "doe",
"age" : 26,
"address" : {
"streetAddress": "naist street",
"city" : "Nara",
"postalCode" : "630-0192"
},
"phoneNumbers": [
{
"type" : "Mobile",
"number": "0123-4567-8888"
},
{
"type" : "home",
"number": "0123-4567-8910"
}
]
}
I intend to change the value of Mobile number within my karate code and use the Json as my request with the following lines
Karate Code:
* def reqJson = read('TestInput.json')
* karate.set('reqJson','$.phoneNumbers[?(#.type=="Mobile")].number',"999999999")
Then print reqJson
The output of the print statement doesn't have the json updated with the number for Mobile.
Alternatively, I've also used the below line to set the variable, but this hasn't worked either:
* set reqJson.phoneNumbers[?(#.type=="Mobile")].number = "99999999"
Is this possible via Karate? If Yes can someone please point me to the place where I'm going wrong or an alternative approach to achieve my scenario.
Thanks.

You can't use JsonPath to mutate. Directly access the path or use a map() operation: https://github.com/karatelabs/karate#json-transforms
This is just one example assuming the JSON is in a variable called body. Take some time to get used to JSON transforms.
* body.phoneNumbers = body.phoneNumbers.map(x => { x.number = '999'; return x })

Related

How to escape "#" when reading from a JSON response?

Let's say I have below sample JSON response from which I want to extract value for "#type":
{
"firstName": "John",
"lastName" : "doe",
"age" : 26,
"phoneNumbers": [
{
"#type" : "iPhone",
"number": "0123-4567-8888"
},
{
"#type" : "home",
"number": "0123-4567-8910"
}
]
}
Validated using:- http://jsonpath.com/
This works for "number":
$.phoneNumbers.[number]
But cannot get value for "#type":
$.phoneNumbers.[#type]
Tried multiple ways but no luck.
Thanks!
Edits:- added another value in the array for "home", now indexing logic [0,1] doesn't work. Even tried with [:] to fetch all values, but no luck.
You can read in this documentation:
Please note, that the return value of jsonPath is an array, which is
also a valid JSON structure.
So basically it always returns an array.
var phoneTypes = jsonPath(json,"$.phoneNumbers.[#type]");
result
["iPhone","home"]
if you want one phone you have to use phoneTypes[0] for iPhone
but I higly recommend you to fix your json using this code
var fixedJson= JSON.parse(JSON.stringify(json).replaceAll("\"#type\"","\"type\"" ));
in this case you can use the real search
var homePhone = jsonPath(fixedJson,"$.phoneNumbers[?(#.type =='home')]")[0].number;
output
0123-4567-8910

JPath for partial query match

I'm trying to learn json jpath query. I have successfully been able to return data based on exact searches.
For example at the site: https://jsonpath.com/ I can successfully retrieve the type of phone based on phone number:
JSON
{
"firstName": "John",
"lastName" : "doe",
"age" : 26,
"address" : {
"streetAddress": "naist street",
"city" : "Nara",
"postalCode" : "630-0192"
},
"phoneNumbers": [
{
"type" : "iPhone",
"number": "0123-4567-8888"
},
{
"type" : "home",
"number": "0123-4567-8910"
}
]
}
Query
$.[?(#.number== '0123-4567-8888')].type
However I can't find any examples that show me how to match a partial search result. I'm trying to write a query where I provide just "0123" and hence get back both "home" and "iPhone" returned as results.How can I do this?
You can use =~ match filter operator which allows providing a regular expression instead of strict value so given you amend your query like:
$.phoneNumbers[?(#.number=~/.*0123.*/)].type
you will get both types as the result:
More information: JMeter's JSON Path Extractor Plugin - Advanced Usage Scenarios

How can i match fields with wildcards using jq?

I have a JSON object of the following form:
{
"Task11c-0-20181209-12:59:30-65611" : {
"attributes" : {
"configname" : "Task11c",
"datetime" : "20181209-12:59:30",
"experiment" : "Task11c",
"inifile" : "lab1.ini",
"iterationvars" : "",
"iterationvarsf" : "",
"measurement" : "",
"network" : "Manhattan1_1C",
"processid" : "65611",
"repetition" : "0",
"replication" : "#0",
"resultdir" : "results",
"runnumber" : "0",
"seedset" : "0"
},
......
},
......
"Task11b-12-20181209-13:03:17-65612" : {
....
....
},
.......
}
I reported only the first part, but in general I have many other sub-objects which match a string like Task11c-0-20181209-12:59:30-65611. They all have in common the initial word Task. I want to extract the processid from each sub-object. I'm trying to use a wildcard like in bash, but it seems not to be possible.
I also read about the match() function, but it works with strings and not json objects.
Thanks for the support.
Filter keys that start with Test and get only the attribute of your choice using the select() expression
jq 'to_entries[] | select(.key|startswith("Task")).value.attributes.processid' json

In rxjs, I try to fetch all the data first then I need to proceed to next line

In Angular 5, I have observable array in service and I am subscribing this in component. And in the next line of statement I am checking whether the data was populated or not. But I found variable is not populated yet.
https://github.com/vsaravanan/ngx-mat-select-search.git
ERROR TypeError: Cannot read property 'slice' of undefined
Error # this.filteredBanksMulti.next(this.banks.slice());
I have a sample data running from jsonserver # port 3000
"banks" :
[
{ "name" : "apphugIndia", "id": "A"},
{ "name" : "batHugFr", "id": "B"},
{ "name" : "Bank C (France)", "id": "C"},
{ "name" : "hungary", "id": "D"},
{ "name" : "Hungary", "id": "E"},
{ "name" : "Bank F (Italy)", "id": "F"}
]
How to resolve this issue?
if you are doing like this
this.httpCall.getData().subscribe(data=>this.recoreds = data);
this.records
then its not going to work as , you call to server is still not complete you must need to wait for data to populate , that means you can do operation in subscribe method only.
to avoid issue you need to put you code in subscribe
this.httpCall.getData().subscribe(data=> {
this.records = data;
//do code here which uses this.records
});

is it possible to extract the specific data in a JSON data , without reading all the values

I have this JSON Data .
My question is that , is it possible to extract the specific data in a JSON data , without reading all the values .
I mean is it possible to query the data as we do in SQL ??
{ "_id" : ObjectId("4e61501e6a73bc73f82f91f3"), "created_at" : "2011-09-02 17:52:30.285", "cust_id" : "sdtest", "moduleName" : "balances", "responses" : [
{
"questionNum" : "1",
"answer" : "Hard",
"comments" : "is that you john wayne?"
},
{
"questionNum" : "2",
"answer" : "Somewhat",
"comments" : "ARg!"
},
{
"questionNum" : "3",
"answer" : "",
"comments" : "Yes"
}
] }
Yes, but you will need to write extra code to do it, or use a third party library. There are a few available: http://www.google.co.uk/search?q=json+linq+sql
Well, unless you use an incremental JSON parser, you'll have to parse the whole JSON first. After that, it depends on your programming language's abilities of how you can filter. For example, in Python
import json
obj = json.loads(jsonData)
answeredQuestions = filter(lambda response: response.answer, obj["responses"])