ruby json get values from array - arrays

I have a this json that has a arrays in it.
How can i get :
- full_text,
- picture link : media_url_https from media and from extended_entities
- url from entities in urls
- lang
[{
"created_at": "Thu Oct 12 14:42:03 +0000 2017",
"id": 9184869314823331890,
"id_str": "9184869314823331890",
"full_text": "trying some stuff! \nhttps://somewebsite.com/emjc1MLAbD\n\uf6430\nWhat bird is this? What is its name? It has beautiful feathers. Love the mix of green, white. https://somewebsite.com/q3IqrfVcUz",
"truncated": false,
"display_text_range": [0, 139],
"entities": {
"hashtags": [],
"symbols": [],
"user_mentions": [],
"urls": [{
"url": "https://somewebsite.com/emjc1MLAbD",
"expanded_url": "https://www.pexels.com/royalty-free-images/",
"display_url": "pexels.com/royalty-free-i\u2026",
"indices": [20, 43]
}],
"media": [{
"id": 918486209067827200,
"id_str": "918486209067827200",
"indices": [140, 163],
"media_url": "http://pbs.twimg.com/media/DL8eVz6VQAA4VHn.jpg",
"media_url_https": "https://pbs.twimg.com/media/DL8eVz6VQAA4VHn.jpg",
"url": "https://somewebsite.com/q3IqrfVcUz",
"display_url": "pic.twitter.com/q3IqrfVcUz",
"expanded_url": "https://twitter.com/DevAdama/status/918486931482333189/photo/1",
"type": "photo",
"sizes": {
"small": {
"w": 680,
"h": 482,
"resize": "fit"
},
"medium": {
"w": 1200,
"h": 850,
"resize": "fit"
},
"thumb": {
"w": 150,
"h": 150,
"resize": "crop"
},
"large": {
"w": 1939,
"h": 1374,
"resize": "fit"
}
}
}]
},
"extended_entities": {
"media": [{
"id": 918486209067827200,
"id_str": "918486209067827200",
"indices": [140, 163],
"media_url": "http://pbs.twimg.com/media/DL8eVz6VQAA4VHn.jpg",
"media_url_https": "https://pbs.twimg.com/media/DL8eVz6VQAA4VHn.jpg",
"url": "https://somewebsite.com/q3IqrfVcUz",
"display_url": "pic.twitter.com/q3IqrfVcUz",
"expanded_url": "https://twitter.com/DevAdama/status/918486931482333189/photo/1",
"type": "photo",
"sizes": {
"small": {
"w": 680,
"h": 482,
"resize": "fit"
},
"medium": {
"w": 1200,
"h": 850,
"resize": "fit"
},
"thumb": {
"w": 150,
"h": 150,
"resize": "crop"
},
"large": {
"w": 1939,
"h": 1374,
"resize": "fit"
}
}
}]
},
"metadata": {
"iso_language_code": "en",
"result_type": "recent"
},
"source": "Twitter Web Client",
"in_reply_to_status_id": null,
"in_reply_to_status_id_str": null,
"in_reply_to_user_id": null,
"in_reply_to_user_id_str": null,
"in_reply_to_screen_name": null,
"user": {
"id": 915243599930982401,
"id_str": "915243599930982401",
"name": "devAdama",
"screen_name": "DevAdama",
"location": "",
"description": "",
"url": null,
"entities": {
"description": {
"urls": []
}
},
"protected": false,
"followers_count": 0,
"friends_count": 0,
"listed_count": 0,
"created_at": "Tue Oct 03 15:54:13 +0000 2017",
"favourites_count": 0,
"utc_offset": null,
"time_zone": null,
"geo_enabled": false,
"verified": false,
"statuses_count": 2,
"lang": "en",
"contributors_enabled": false,
"is_translator": false,
"is_translation_enabled": false,
"profile_background_color": "000000",
"profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png",
"profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png",
"profile_background_tile": false,
"profile_image_url": "http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png",
"profile_image_url_https": "https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png",
"profile_link_color": "981CEB",
"profile_sidebar_border_color": "000000",
"profile_sidebar_fill_color": "000000",
"profile_text_color": "000000",
"profile_use_background_image": false,
"has_extended_profile": false,
"default_profile": false,
"default_profile_image": true,
"following": false,
"follow_request_sent": false,
"notifications": false,
"translator_type": "none"
},
"geo": null,
"coordinates": null,
"place": null,
"contributors": null,
"is_quote_status": false,
"retweet_count": 0,
"favorite_count": 0,
"favorited": false,
"retweeted": false,
"possibly_sensitive": false,
"lang": "en"
}, {
"created_at": "Wed Oct 04 17:33:29 +0000 2017",
"id": 915630969218064385,
"id_str": "915630969218064385",
"full_text": "hola!",
"truncated": false,
"display_text_range": [0, 5],
"entities": {
"hashtags": [],
"symbols": [],
"user_mentions": [],
"urls": []
},
"metadata": {
"iso_language_code": "es",
"result_type": "recent"
},
"source": "Twitter Web Client",
"in_reply_to_status_id": null,
"in_reply_to_status_id_str": null,
"in_reply_to_user_id": null,
"in_reply_to_user_id_str": null,
"in_reply_to_screen_name": null,
"user": {
"id": 915243599930982401,
"id_str": "915243599930982401",
"name": "devAdama",
"screen_name": "DevAdama",
"location": "",
"description": "",
"url": null,
"entities": {
"description": {
"urls": []
}
},
"protected": false,
"followers_count": 0,
"friends_count": 0,
"listed_count": 0,
"created_at": "Tue Oct 03 15:54:13 +0000 2017",
"favourites_count": 0,
"utc_offset": null,
"time_zone": null,
"geo_enabled": false,
"verified": false,
"statuses_count": 2,
"lang": "en",
"contributors_enabled": false,
"is_translator": false,
"is_translation_enabled": false,
"profile_background_color": "000000",
"profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png",
"profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png",
"profile_background_tile": false,
"profile_image_url": "http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png",
"profile_image_url_https": "https://website.com/sticky/default_profile_images/default_profile_normal.png",
"profile_link_color": "981CEB",
"profile_sidebar_border_color": "000000",
"profile_sidebar_fill_color": "000000",
"profile_text_color": "000000",
"profile_use_background_image": false,
"has_extended_profile": false,
"default_profile": false,
"default_profile_image": true,
"following": false,
"follow_request_sent": false,
"notifications": false,
"translator_type": "none"
},
"geo": null,
"coordinates": null,
"place": null,
"contributors": null,
"is_quote_status": false,
"retweet_count": 0,
"favorite_count": 0,
"favorited": false,
"retweeted": false,
"lang": "es"
}]

Maybe not tidy but still you can try do the following:
require 'json'
test = JSON.parse(json)
test.each {|k|
p "============================"
full_text = k['full_text'] unless k['full_text'].nil?
urls = k['entities']['urls'] unless k['entities']['urls'].nil?
urls.each {|u|
entities_url = u['url'] unless u['url'].nil?
p "Url: #{entities_url}" }
lang = k['lang'] unless k['lang']
media = k['entities']['media']
extended_media = k['extended_entities']['media'] unless k['extended_entities'].nil?
p "Full text: #{full_text}" unless full_text.nil?
media.each {|u|
p "Media url: #{u['media_url_https']}" unless u['media_url_https'].nil?
} unless media.nil?
extended_media.each {|u|
p "Extended url: #{u['media_url_https']}" unless u['media_url_https'].nil?
} unless extended_media.nil?
p "Lang: #{lang}" unless lang.nil?
p "============================="
}

Related

node red function add and remove object from context array

I have a for loop in the node red function that a the start of the function I get the array from the context
var alarmArray = flow.get("alarmArray")
and after I need to push object on the array I have do this but I'm not pusching on the flow context array but in the local array
alarmArray.push({
key: "Low air pressure",
value: alarm1Cip
});
flow.set("alarm1CipOld",alarm1Cip);
and after in the for loop I need to remove the object from the context but in my way I remove it from local array
for (var key in alarmArray){
node.warn(key);
msg.payload = {
"title": alarmArray[key].key,
"isActive":alarmArray[key].value
};
node.send(msg)
delete alarmArray[key]
}
how can I manage to add and remove object in the context array?
thanks
The problem here is that NodeJS is a pass by reference language. This means that there are not 2 arrays here, only 1 that has 2 handles (var alarmArray and flow.get('alarmArray'))
This means that anything pushed/deleted on the "local" copy is also getting pushed/deleted to the copy in the context.
The only way to do what you want will be to make a deep copy of the array every time you recover it from the context and then work on the copy locally.
Assuming the array only holds simple objects then the following should work:
var alarmArray = JSON.parse(JSON.stringify(flow.get('alarmArray')))
If you want to save your changes you just have to reload the mutated object in the right context, overwriting the previous value with
flow.set('alarmArray', alarmArray)
You might better to use global.set instead of flow.set
This might help you.
[
{
"id": "133329daaceb6bb3",
"type": "tab",
"label": "flow 3",
"disabled": false,
"info": "",
"env": []
},
{
"id": "c80bec9a15b703f6",
"type": "inject",
"z": "133329daaceb6bb3",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 140,
"y": 140,
"wires": [
[
"8687551e01cd2045"
]
]
},
{
"id": "8687551e01cd2045",
"type": "function",
"z": "133329daaceb6bb3",
"name": "msg_1",
"func": "global.set(\"msg_1\",\"test\");\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 280,
"y": 140,
"wires": [
[]
]
},
{
"id": "103b03c39c8d9cae",
"type": "debug",
"z": "133329daaceb6bb3",
"name": "debug 29",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 500,
"y": 300,
"wires": []
},
{
"id": "c043cba9f34ba574",
"type": "inject",
"z": "133329daaceb6bb3",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 140,
"y": 180,
"wires": [
[
"e674c706437cc0f3"
]
]
},
{
"id": "e674c706437cc0f3",
"type": "function",
"z": "133329daaceb6bb3",
"name": "msg_2 ",
"func": "global.set(\"msg_2\",\"hello\");\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 280,
"y": 180,
"wires": [
[]
]
},
{
"id": "11f8fb75d4c4e6c0",
"type": "inject",
"z": "133329daaceb6bb3",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "1",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 150,
"y": 300,
"wires": [
[
"1346e34e8c83b2dc"
]
]
},
{
"id": "1346e34e8c83b2dc",
"type": "function",
"z": "133329daaceb6bb3",
"name": "check if 2 msg set",
"func": "var msg1 = global.get(\"msg_1\");\nvar msg2 = global.get(\"msg_2\");\n\nif(msg1 && msg2){\n msg.payload=\"both message arrived!\";\n}\nelse{\n msg.payload=\"Nope. Not yet.\";\n}\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 330,
"y": 300,
"wires": [
[
"103b03c39c8d9cae"
]
]
},
{
"id": "62d522a844321ef9",
"type": "inject",
"z": "133329daaceb6bb3",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 540,
"y": 140,
"wires": [
[
"6d109daff443dade"
]
]
},
{
"id": "6d109daff443dade",
"type": "function",
"z": "133329daaceb6bb3",
"name": "reset",
"func": "global.set(\"msg_1\",null);\nglobal.set(\"msg_2\",null);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 690,
"y": 140,
"wires": [
[]
]
},
{
"id": "4e1848c867860d5f",
"type": "comment",
"z": "133329daaceb6bb3",
"name": "Here gonna auto-run",
"info": "",
"x": 170,
"y": 260,
"wires": []
},
{
"id": "3102e176923a8fad",
"type": "comment",
"z": "133329daaceb6bb3",
"name": "Check what if both inject clicked",
"info": "",
"x": 210,
"y": 100,
"wires": []
}
]

While Loop in Node Red

I have one system that is connected to some sensors. The main job is to send error numbers when one or more of the sensors are on.
In order to print the error description I have one csv-File with two columns, the first one with the numbers and the second one with the description.
In order to make this task I have created one flow in Node-Red:
In one line I save the array with the error numbers coming from the system in one flow variable (RandomNum).
In another line I read the csv-file with the error description, I transform it in an array of objects and then in fuction node I make a search in order to find the error number and the description.
The search function has as entance the array of objects. I save the flow variable (RandomNum) in an array (ranNum) and I define a new array (newMsg) where I save the description of the errors.
Then I use a while-loop in order to go through the array of objects and compare the value of the first column of this array with the number in ranNum. Then I save the description of the error in the array newMsg and I do this while-loop for each value of the ranNum array.
And here is my problem. When I execute the flow, it works correctly for the first value of the array ranNum but only for this. I get only the description of the first number in the ranNum array as payload, it looks like as the while-loop is used only once, and then it breaks and gives me the array newMsg.
When I check in the Conetxt, RandomNum is one array,
An when I ask to get the array ranNum, it's also an array,
I have check the while-loop at least 20-times, and I have did not found why it does not work.
Can anyone help me with this topic? Is there a problem with the flow variable or there is big difference between JavaScript and NodeJS that I did not found?
Here is the flow I have created:
[
{
"id": "b1d8b61d0ed5a5da",
"type": "tab",
"label": "Flow Test",
"disabled": false,
"info": ""
},
{
"id": "d677b342ccc51f1b",
"type": "inject",
"z": "b1d8b61d0ed5a5da",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 140,
"y": 280,
"wires": [
[
"e2d5187d2e705892",
"a167b5a81e0b36ba"
]
]
},
{
"id": "7aa6e0bcbdf67c1c",
"type": "file in",
"z": "b1d8b61d0ed5a5da",
"name": "ReadAlarms",
"filename": "/home/DMT/Dokumente/DB_Test/alarms.csv",
"format": "utf8",
"chunk": false,
"sendError": false,
"encoding": "none",
"allProps": false,
"x": 530,
"y": 280,
"wires": [
[
"f2ab599d26fd7ca5",
"94ae4b1ea29d9fe2"
]
]
},
{
"id": "f2ab599d26fd7ca5",
"type": "debug",
"z": "b1d8b61d0ed5a5da",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 750,
"y": 220,
"wires": []
},
{
"id": "94ae4b1ea29d9fe2",
"type": "csv",
"z": "b1d8b61d0ed5a5da",
"name": "ConvertAlarms",
"sep": ",",
"hdrin": false,
"hdrout": "all",
"multi": "mult",
"ret": "\\n",
"temp": "",
"skip": "0",
"strings": true,
"include_empty_strings": "",
"include_null_values": "",
"x": 760,
"y": 280,
"wires": [
[
"9a3547cc81c2d2bb",
"ff9175d01efa5ce4"
]
]
},
{
"id": "9a3547cc81c2d2bb",
"type": "debug",
"z": "b1d8b61d0ed5a5da",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 990,
"y": 220,
"wires": []
},
{
"id": "1a270df6276485c4",
"type": "debug",
"z": "b1d8b61d0ed5a5da",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1230,
"y": 220,
"wires": []
},
{
"id": "ff9175d01efa5ce4",
"type": "function",
"z": "b1d8b61d0ed5a5da",
"name": "SearchFailureS7",
"func": "let i=0;\nlet ranNum = [];\nranNum = flow.get(\"RandomNum\");\nlet newMsg = [];\n\nwhile (i<ranNum.length){\n\n let n = ranNum[i];\n newMsg[newMsg.length] = {payload: msg.payload[n].col2};\n i = i + 1;\n \n}\n\nreturn newMsg;\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1010,
"y": 280,
"wires": [
[
"1a270df6276485c4"
]
]
},
{
"id": "a167b5a81e0b36ba",
"type": "function",
"z": "b1d8b61d0ed5a5da",
"name": "RandomArray",
"func": "const num=[];\nvar i;\n\nfor (i=0; i<3; i++){\n \nnum[i] = Math.floor(Math.random() * 9);\n\n}\n\nrandArray = {payload: num}\n\nreturn randArray;\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 340,
"y": 400,
"wires": [
[
"c011fa2387db0d18",
"9c400785174973e9"
]
]
},
{
"id": "c011fa2387db0d18",
"type": "debug",
"z": "b1d8b61d0ed5a5da",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 530,
"y": 340,
"wires": []
},
{
"id": "9c400785174973e9",
"type": "function",
"z": "b1d8b61d0ed5a5da",
"name": "",
"func": "flow.set(\"RandomNum\",msg.payload);\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 520,
"y": 400,
"wires": [
[]
]
},
{
"id": "e2d5187d2e705892",
"type": "delay",
"z": "b1d8b61d0ed5a5da",
"name": "Delay 10ms",
"pauseType": "delay",
"timeout": "10",
"timeoutUnits": "milliseconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"allowrate": false,
"outputs": 1,
"x": 330,
"y": 280,
"wires": [
[
"7aa6e0bcbdf67c1c"
]
]
}
]
So, I finally found it. The payload in the while-loop was breaking the loop immediately. So I changed the code in the while-loop using a similar code I found on the net. Now it works.
Old code:
let i=0;
let ranNum = [];
ranNum = flow.get("RandomNum");
let newMsg = [];
while (i<ranNum.length){
let n = ranNum[i];
newMsg[newMsg.length] = {payload: msg.payload[n].col2};
i = i + 1;
}
return newMsg;
New code
let i=0;
let ranNum = [];
ranNum = flow.get("RandomNum");
let newMsg = [];
while (i<ranNum.length){
let n = ranNum[i];
let description = msg.payload[n].col2;
newMsg.push(description);
i = i + 1;
}
msg.payload = newMsg;
return msg;

How to extract data from nested Json in Jmeter using Json Extractor

{"data": {"callOrders": [{
"promotionId": null,
"Promotion": null,
"Lines": [
{
"id": 5105808,
"quantity": 10,
"skuId": 769,
"callId": 494285,
"skuBatchId": 733,
"amountDetails": {
"rate": 197.53,
"grossAmount": 2232.089,
"netAmount": 2232.089,
"taxAmount": 256.789,
"taxableAmount": 1975.3,
"subTotal": 1975.3,
"billDiscount": 0,
"tradeDiscount": 0,
"discountAmount": 0,
"promotionDiscount": 0,
"topUpDiscount": 0,
"__typename": "AmountDetail"
},
"rateDetails": {
"rlp": 197.53,
"rlpWithVat": 223.2089,
"netPrice": 197.53,
"netPriceWithVat": 223.2089,
"__typename": "RateDetail"
},
"SKU": {
"id": 769,
"title": "H&S 2in1 Active Protect 180 ml x 24 [82302894]",
"__typename": "SKU"
},
"SKUBatch": {
"priceDetails": {
"rlp": 197.53,
"dlp": 186.35,
"vatPercentage": 0.13,
"mrpSrp": 250,
"mrpStatus": true,
"__typename": "SKUPrice"
},
"batchDetails": {
"batchNumber": "DEFAULT_BATCH",
"__typename": "SKUBatch"
},
"usageDate": {
"manufacture": "0000-00-00",
"expiry": "0000-00-00",
"__typename": "SKUUsage"
},
"updatedAt": "2019-11-05",
"active": true,
"__typename": "SKUBatchRate"
},
"Promotion": {
"id": null,
"title": null,
"type": null,
"scope": null,
"criteria": null,
"__typename": "Promotion"
},
"promotionId": null,
"distributorId": 16,
"__typename": "Line",
"inStock": "INSTOCK",
"freeSku": false,
"focusedSku": false
},
{
"id": 5105809,
"quantity": 50,
"skuId": 95,
"callId": 494285,
"skuBatchId": 111,
"amountDetails": {
"rate": 56.89,
"grossAmount": 3214.2852,
"netAmount": 3214.285,
"taxAmount": 369.785,
"taxableAmount": 2844.5,
"subTotal": 2844.5,
"billDiscount": 0,
"tradeDiscount": 0,
"discountAmount": 0,
"promotionDiscount": 0,
"topUpDiscount": 0,
"__typename": "AmountDetail"
},
"rateDetails": {
"rlp": 56.89,
"rlpWithVat": 64.2857,
"netPrice": 56.89,
"netPriceWithVat": 64.2857,
"__typename": "RateDetail"
},
"SKU": {
"id": 95,
"title": "Whisper Choice 6s x 96 [82252488]",
"__typename": "SKU"
},
"SKUBatch": {
"priceDetails": {
"rlp": 56.89,
"dlp": 53.67,
"vatPercentage": 0.13,
"mrpSrp": 72,
"mrpStatus": true,
"__typename": "SKUPrice"
},
"batchDetails": {
"batchNumber": "DEFAULT_BATCH",
"__typename": "SKUBatch"
},
"usageDate": {
"manufacture": "0000-00-00",
"expiry": "0000-00-00",
"__typename": "SKUUsage"
},
"updatedAt": "2016-08-15",
"active": true,
"__typename": "SKUBatchRate"
},
"Promotion": {
"id": null,
"title": null,
"type": null,
"scope": null,
"criteria": null,
"__typename": "Promotion"
},
"promotionId": null,
"distributorId": 16,
"__typename": "Line",
"inStock": "INSTOCK",
"freeSku": false,
"focusedSku": false
},
{
"id": 5105810,
"quantity": 10,
"skuId": 82,
"callId": 494285,
"skuBatchId": 551,
"amountDetails": {
"rate": 281.88,
"grossAmount": 3185.244,
"netAmount": 3185.244,
"taxAmount": 366.444,
"taxableAmount": 2818.8,
"subTotal": 2818.8,
"billDiscount": 0,
"tradeDiscount": 0,
"discountAmount": 0,
"promotionDiscount": 0,
"topUpDiscount": 0,
"__typename": "AmountDetail"
},
"rateDetails": {
"rlp": 281.88,
"rlpWithVat": 318.5244,
"netPrice": 281.88,
"netPriceWithVat": 318.5244,
"__typename": "RateDetail"
},
"SKU": {
"id": 82,
"title": "Ariel Oxyblu 1 kg x 24 [82250306]",
"__typename": "SKU"
},
"SKUBatch": {
"priceDetails": {
"rlp": 281.88,
"dlp": 268.45,
"vatPercentage": 0.13,
"mrpSrp": 344,
"mrpStatus": true,
"__typename": "SKUPrice"
},
"batchDetails": {
"batchNumber": "DEFAULT_BATCH",
"__typename": "SKUBatch"
},
"usageDate": {
"manufacture": "0000-00-00",
"expiry": "0000-00-00",
"__typename": "SKUUsage"
},
"updatedAt": "2018-01-31",
"active": true,
"__typename": "SKUBatchRate"
},
"Promotion": {
"id": null,
"title": null,
"type": null,
"scope": null,
"criteria": null,
"__typename": "Promotion"
},
"promotionId": null,
"distributorId": 16,
"__typename": "Line",
"inStock": "INSTOCK",
"freeSku": false,
"focusedSku": false
}
],
"__typename": "PromotionOrder"
}]}}
Using $..Lines..id I am getting this
[
5105808,
769,
null,
5105809,
95,
null,
5105810,
82,
null
]
But I want to get value [ 5105808, 5105809, 5105810] only. What should be the way to achieve it?
This is a possible solution:
$..[?(#.skuId)].id
This gets elements that have the skuId attribute and extracts the id attribute.
You're using .. which is a deep scan operator which means that you're looking for all id attribute values no matter where they're located in the JSON.
If you want to get only id of the attributes which are direct children of the Lines object - you need to amend your query to look like: $..Lines[*].id
Demo:
More information: JMeter's JSON Path Extractor Plugin - Advanced Usage Scenarios

Array parsing and converting to new array List

How to convert below array to specific output?
Input:
[
{
"id": "9664581",
"isSelected": true,
"isExpanded": false,
"disabled": false,
"cells": [
{
"id": "9664581:att_name",
"value": "Test1 att_name",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "att_name"
}
},
{
"id": "9664581:att_email",
"value": "test1#gmail.com",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "att_email"
}
},
{
"id": "9664581:comp_name",
"value": "Test1 comp_name",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "comp_name"
}
},
{
"id": "9664581:attendee_ctry",
"value": "Test cnt",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "attendee_ctry"
}
},
{
"id": "9664581:sources",
"value": "Test DB",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "sources"
}
}
]
},
{
"id": "9528552",
"isSelected": true,
"isExpanded": false,
"disabled": false,
"cells": [
{
"id": "9528552:att_name",
"value": "Test2 att_name",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "att_name"
}
},
{
"id": "9528552:att_email",
"value": "Test2#gmail.com",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "att_email"
}
},
{
"id": "9528552:comp_name",
"value": "Dsd comp_name",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "comp_name"
}
},
{
"id": "9528552:attendee_ctry",
"value": "Test2 cnt",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "attendee_ctry"
}
},
{
"id": "9528552:sources",
"value": "Test2 DB",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "sources"
}
}
]
}
]
output should be like
output:
[
{
"id": "9664581",
"name": "Test1 att_name",
"email": test1#gmail.com
},
{
"id": "9528552",
"name": "Test2 att_name",
"email": test2#gmail.com
}
]
You need to understand your data.
It appears that the id comes right off of each object. As for the name and email, those are the values of the first and second cell. This turns into a trivial mapping.
You could also try to look-up the cells by their header:
function transformData(data) {
return data.map(item => {
return {
id : item.id,
name : item.cells.find(cell => cell.info.header.endsWith('name')).value,
email : item.cells.find(cell => cell.info.header.endsWith('email')).value
};
});
}
console.log(transformData(getData()));
function transformData(data) {
return data.map(item => {
return {
id : item.id,
name : item.cells[0].value,
email : item.cells[1].value
};
});
}
function getData() {
return [{
"id": "9664581",
"isSelected": true,
"isExpanded": false,
"disabled": false,
"cells": [{
"id": "9664581:att_name",
"value": "Test1 att_name",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "att_name"
}
}, {
"id": "9664581:att_email",
"value": "test1#gmail.com",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "att_email"
}
}, {
"id": "9664581:comp_name",
"value": "Test1 comp_name",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "comp_name"
}
}, {
"id": "9664581:attendee_ctry",
"value": "Test cnt",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "attendee_ctry"
}
}, {
"id": "9664581:sources",
"value": "Test DB",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "sources"
}
}]
}, {
"id": "9528552",
"isSelected": true,
"isExpanded": false,
"disabled": false,
"cells": [{
"id": "9528552:att_name",
"value": "Test2 att_name",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "att_name"
}
}, {
"id": "9528552:att_email",
"value": "Test2#gmail.com",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "att_email"
}
}, {
"id": "9528552:comp_name",
"value": "Dsd comp_name",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "comp_name"
}
}, {
"id": "9528552:attendee_ctry",
"value": "Test2 cnt",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "attendee_ctry"
}
}, {
"id": "9528552:sources",
"value": "Test2 DB",
"isEditable": false,
"isEditing": false,
"isValid": true,
"errors": null,
"info": {
"header": "sources"
}
}]
}];
}
.as-console-wrapper { top: 0; max-height: 100% !important; }
You could do this:
let output = input.map(v => {
let name = '';
let email = '';
v.cells.map(obj => {
if(obj.info.header === 'att_name') {
name = obj.value
}
if(obj.info.header === 'att_email') {
email = obj.value
}
return
})
return {
"id": v.id,
"name": name,
"email": email
}
})

LoopbackJS, Angularjs sdk, model.$save duplicates

I am using lopbackJS AngularJS sdk.I have a model for sites (id(pk) int, name varchar(50), url varchar(100)).
When i try to update name and calling site.save(), record became duplicated. If i try to update other fields except name, update succeeded.
Any suggestion?
site.json :
{
"name": "Site",
"base": "PersistedModel",
"idInjection": false,
"mysql": {
"schema": "myDB",
"table": "Site"
},
"properties": {
"id": {
"type": "Number",
"id": true,
"required": true,
"length": null,
"precision": 10,
"scale": 0,
"mysql": {
"columnName": "Id",
"dataType": "int",
"dataLength": null,
"dataPrecision": 10,
"dataScale": 0,
"nullable": "N"
},
"_selectable": true
},
"xmlFieldId": {
"type": "Number",
"required": false,
"length": null,
"precision": 10,
"scale": 0,
"mysql": {
"columnName": "XmlFieldId",
"dataType": "int",
"dataLength": null,
"dataPrecision": 10,
"dataScale": 0,
"nullable": "Y"
},
"_selectable": true
},
"name": {
"type": "String",
"required": true,
"length": 150,
"precision": null,
"scale": null,
"mysql": {
"columnName": "Name",
"dataType": "varchar",
"dataLength": 150,
"dataPrecision": null,
"dataScale": null,
"nullable": "N"
},
"_selectable": true
},
"url": {
"type": "String",
"required": true,
"length": 600,
"precision": null,
"scale": null,
"mysql": {
"columnName": "Url",
"dataType": "varchar",
"dataLength": 600,
"dataPrecision": null,
"dataScale": null,
"nullable": "Y"
},
"_selectable": true
},
"active": {
"type": "Boolean",
"required": true,
"mysql": {
"columnName": "Active",
"dataType": "BOOL",
"nullable": "N"
},
"_selectable": true
},
"xmlUrl": {
"type": "String",
"required": false,
"length": 600,
"precision": null,
"scale": null,
"mysql": {
"columnName": "XmlUrl",
"dataType": "varchar",
"dataLength": 600,
"dataPrecision": null,
"dataScale": null,
"nullable": "Y"
},
"_selectable": true
},
"private": {
"type": "Boolean",
"required": true,
"mysql": {
"columnName": "Private",
"dataType": "BOOL",
"nullable": "N"
},
"_selectable": true
},
"xmlUrlValidated": {
"type": "Boolean",
"required": true,
"length": null,
"precision": 5,
"scale": 0,
"mysql": {
"columnName": "XmlUrlValidated",
"dataType": "BOOL",
"nullable": "N"
},
"_selectable": true
},
"xmlUrlValUpdate": {
"type": "Date",
"required": false,
"length": null,
"precision": null,
"scale": null,
"mysql": {
"columnName": "XmlUrlValUpdate",
"dataType": "datetime",
"dataLength": null,
"dataPrecision": null,
"dataScale": null,
"nullable": "Y"
},
"_selectable": true
},
"imgBaseUrl": {
"type": "String",
"required": false,
"length": 200,
"precision": null,
"scale": null,
"mysql": {
"columnName": "ImgBaseUrl",
"dataType": "varchar",
"dataLength": 200,
"dataPrecision": null,
"dataScale": null,
"nullable": "Y"
},
"_selectable": true
},
"credit": {
"type": "Number",
"required": false,
"length": null,
"precision": 8,
"scale": 2,
"mysql": {
"columnName": "Credit",
"dataType": "decimal",
"dataLength": null,
"dataPrecision": 8,
"dataScale": 2,
"nullable": "N"
},
"_selectable": true
}
},
"validations": [],
"relations": {
"siteCategorySteps": {
"type": "hasMany",
"model": "SiteCategoryStep",
"foreignKey": ""
},
"siteProdSchemas": {
"type": "hasOne",
"model": "SiteProdSchema",
"foreignKey": ""
},
"products": {
"type": "hasMany",
"model": "Product",
"foreignKey": ""
},
"users": {
"type": "hasMany",
"model": "UyguncaUser",
"foreignKey": "siteId"
}
},
"acls": [],
"methods": []
}
Controller :
'use strict';
MyApp.controller('SiteInfoController', ['$rootScope', '$scope', '$timeout', '$animate', 'Site', '$http', 'CheckXmlFile',
function ($rootScope, $scope, $timeout, $animate, Site, $http, CheckXmlFile) {
var site = null;
Site.findOne({
filter: {where: {id: $rootScope.globals.accessToken.user.siteId}}
}, function (fSite) {
site = $scope.site = fSite;
});
$scope.checkXmlUrl = function (showMesg, cb) {
CheckXmlFile.check({
xmlUrl: site.xmlUrl
}, function (res) {
site.xmlUrlValidated = true;
site.$save();
if (showMesg) showMsg({
title: "Bilgi!",
text: res.msg,
type: "success",
confirmButtonText: "Tamam",
}, null);
cb(true);
}, function (err) {
site.xmlUrlValidated = false;
site.$save();
if (showMesg) showMsg({
title: "Hata!",
text: err.data.errMsg,
type: "error",
confirmButtonText: "Tamam",
}, null);
cb(false);
})
};
$scope.save = function () {
!$scope.checkXmlUrl(false, function (err) {
if (!err) {
showMsg({
title: "Uyarı!",
text: "Kayıt yapıldı fakat XML dosya doğrulanamadı. XML dosya doğrulaması yapılmadan ürün bilgileri alınamayacaktır!",
type: "warning",
confirmButtonText: "Tamam",
}, null);
}
else {
showMsg({
title: "Bilgi!",
text: "XML dosya doğrulanarak site bilgileri kaydedilmiştir.",
type: "success",
confirmButtonText: "Tamam",
}, null);
}
});
}
}]);
I found that, 'Site' table has trigger and it prevents to update.
I removed trigger and update works...

Resources