What is the best way to replace text in json? - javascript

So I have a bunch of JSON data and it contains a few fields. for example:
[{
"id": "XXX",
"version": 1,
"head": {
"text": "Main title",
"sub": {
"value": "next"
},
"place": "secondary"
},
"body": [{
"id": "XXX1",
"info": "three little birds",
"extended": {
"spl": {
"text": "song",
"type": {
"value": "a"
}
}
}
},
{
"id": "XXX2",
"info": [
"how are you?"
],
"extended": {
"spl": {
"text": "just",
"non-type": {
"value": "abc"
}
}
}
}
]
}]
what I'm trying to do is kind of conversion table (from a different JSON file)
if a field has the value 'a' replace it with 'some other text..' etc.
I have a service for the JSON pipeline, so I guess this is the right place to do the replacement.
so for this example, I have the JSON above and in my conversion table I have the following terms:
next: forward,
song: music,
a: option1,
just: from
etc...

What you are looking for can be achieved with templates. Replace the variable sections with some specific markers that you can find and replace from some external tools such as perl or sed.
For example, you could have a template.json with something like this:
...
"type": {
"value": "##VALUE##"
}
...
Then when you need the actual JSON, you could pass this though an intermediate script that replaces these templates with actual data.
cat template.json | sed -e 's/##VALUE##/my_value/' > target.json
Alternatively, with Perl:
cat template.json | perl -pi -e 's:\#\#VALUE\#\#:my_value:' > target.json

The best way is to parse it, replace the text in the object, and then stringify it.
The next best way is to use a regular expression.
In this example, I catch exceptions if path cannot be indexed, and use ['type'] instead of .type so it will scale to indexing 'non-type' if you wish.
const data = `[{
"id": "XXX",
"version": 1,
"head": {
"text": "Main title",
"sub": {
"value": "next"
},
"place": "secondary"
},
"body": [{
"id": "XXX1",
"info": "three little birds",
"extended": {
"spl": {
"text": "song",
"type": {
"value": "a"
}
}
}
},
{
"id": "XXX2",
"info": [
"how are you?"
],
"extended": {
"spl": {
"text": "just",
"non-type": {
"value": "abc"
}
}
}
}
]
}]
`
const o = JSON.parse(data)
o[0].body.forEach(b => {
try {
if (b.extended.spl['type'].value === 'a') {
b.extended.spl['type'].value = 'CHANGED'
}
} catch (e) {}
})
const newData = JSON.stringify(o, null, 2)
console.log(newData)
A string replace approach will work if you know and can rely on your source conforming, such as the only "value" is inside "type"
const data = `[{
"id": "XXX",
"version": 1,
"head": {
"text": "Main title",
"sub": {
"value": "next"
},
"place": "secondary"
},
"body": [{
"id": "XXX1",
"info": "three little birds",
"extended": {
"spl": {
"text": "song",
"type": {
"value": "a"
}
}
}
},
{
"id": "XXX2",
"info": [
"how are you?"
],
"extended": {
"spl": {
"text": "just",
"non-type": {
"value": "abc"
}
}
}
}
]
}]
`
const newData = data.replace(/"value": "a"/g, '"value": "NEWVALUE"')
console.log(newData)

Related

Creating new json by taking url addresses from existing json and split it up Javascript

I have a json file.
[
{
"line": 1,
"elements": [
{
"start_timestamp": "2022-10-17T20:07:41.706Z",
"steps": [
{
"result": {
"duration": 12216552000,
"status": "passed"
},
"line": 5,
"name": "m0e",
"match": {
"location": "seleniumgluecode.book.user_is_on_homepagee()"
},
"keyword": "Given "
},
{
"result": {
"duration": 2074982200,
"status": "passed"
},
"line": 6,
"name": "m1e1",
"match": {
"location": "seleniumgluecode.book.user_enters_Usernamee()"
},
"keyword": "When "
}
],
"tags": [
{
"name": "#Smokee"
}
]
},
{
"start_timestamp": "2022-10-17T20:08:12.284Z",
"steps": [
{
"result": {
"duration": 12090584100,
"status": "passed"
},
"line": 12,
"name": "m0e2",
"match": {
"location": "seleniumgluecode.book2.user_is_on_homepageee()"
},
"keyword": "Given "
}
],
"tags": [
{
"name": "#Smokee"
}
]
}
],
"name": "Login Featuree",
"description": " Verify if user is able to Login in to the sitee",
"id": "login-featuree",
"keyword": "Feature",
"uri": "file:src/test/java/features/tribe/squad1/kitab.feature",
"tags": []
},
{
"line": 1,
"elements": [
{
"start_timestamp": "2022-10-17T20:08:34.480Z",
"steps": [
{
"result": {
"duration": 11366098500,
"status": "passed"
},
"line": 5,
"name": "m0e",
"match": {
"location": "seleniumgluecode.book.user_is_on_homepagee()"
},
"keyword": "Given "
}
],
"tags": [
{
"name": "#Smokee"
}
]
}
],
"name": "Login Featureefghfgh",
"description": " Verify if user is able to Login in to the sitee",
"id": "login-featureefghfgh",
"keyword": "Feature",
"uri": "file:src/test/java/features/tribe1/squad2/kitab2.feature",
"tags": []
},
{
"line": 19,
"elements": [
{
"start_timestamp": "2022-10-17T20:09:40.836Z",
"steps": [
{
"result": {
"duration": 12761711100,
"status": "passed"
},
"line": 23,
"name": "m0e",
"match": {
"location": "seleniumgluecode.book.user_is_on_homepagee()"
},
"keyword": "Given "
}
],
"tags": [
{
"name": "#Smokee"
}
]
}
],
"name": "X Feature",
"description": " Verify if user is able to Login in to the sitee",
"id": "login-featuree",
"keyword": "Feature",
"uri": "file:src/test/java/features/tribe2/test.feature",
"tags": []
}
]
I am getting url addresses in this array
document.addEventListener("DOMContentLoaded", () => {
var i = report.length;
var array = [];
for(x = 0; x < i; x++){
array.push(report[x].uri.split("/"));
}
console.log(array2);
});
This return me :
0:
(7) ['file:src', 'test', 'java', 'features', 'tribe1', 'squad1', 'kitab.feature']
1:
(7) ['file:src', 'test', 'java', 'features', 'tribe1', 'squad2', 'kitab2.feature']
2:
(6) ['file:src', 'test', 'java', 'features', 'tribe2, kitab3.feature']
I don't need file:src, test, java, features. Deleting them in 3 arrays and getting a unique array like this:
0:
(3) ['tribe1', 'squad1', 'kitab.feature']
1:
(3) ['tribe1', 'squad2', 'kitab2.feature']
2:
(2) ['tribe2, kitab3.feature']
Finally, if there are 2 elements before the .feature, I need to create a new array by considering 1 as squad and 2 as tribe. Like this:
Diagram
[tribe1
squad1
elem
1
2
name
url
squad2
elem
1
2
name
url
tribe2
elem
1
2
name
url
]
How can I do that?. Thank you.
You should try destructing the array. An example is shown below:
[a,b,c,d, ...rest] = ['file:src', 'test', 'java', 'features', 'tribe1', 'squad1', 'kitab.feature']
console.log(rest);
You can transform or create a new array based on input array with this simple logic with the help of Array.map() along with String.split() and Array.splice() method.
Live Demo :
const arr = [
{
"line": 1,
"uri": "file:src/test/java/features/tribe/squad1/kitab.feature"
},
{
"line": 1,
"uri": "file:src/test/java/features/tribe1/squad2/kitab2.feature"
},
{
"line": 19,
"uri": "file:src/test/java/features/tribe2/test.feature"
}
];
const res = arr.map(({ uri}) => uri.split('/').splice(4));
console.log(res);

How can I concatenate this type of JSON in javascript?

How can I concatenate this json to obtain it:
complements = ["XYZ 3, CDE TR, AAA 5", "", "NDP 3, DDD FR"] ?
Each address can contain a set of complements which must be concatenated and separated by a comma.
P.s: I'm using javascript.
P.s2: Complements can be null like in the second group in JSON.
[
{
"postalcode": "1234",
"street": "ABC",
"number": "1",
"complement": [
{
"type": "B",
"name": "XYZ",
"description": "3"
},
{
"type": "C",
"name": "CDE",
"description": "TR"
},
{
"type": "D",
"name": "AAA",
"description": "5"
}
]
},
{
"postalcode": "444",
"street": "No complements",
"number": "5"
},
{
"postalcode": "2222",
"street": "BBB",
"number": "2",
"complement": [
{
"type": "E",
"name": "NDP",
"description": "3"
},
{
"type": "F",
"name": "DDD",
"description": "FR"
}
]
}
];
My code I'm getting this.complementsList.forEach is not a function.
getComplement(addressesResponse){
this.complementsList = JSON.parse(addressesResponse);
this.complementsList.forEach((item) => {
Object.defineProperty(item, 'complements', {
get: function() {
return this.complement.map((c) => `${c.name} ${c.description}`).join(', '); }
})
});
Source: https://salesforce.stackexchange.com/questions/367713/how-to-render-a-json-in-the-same-line-lwc
how i solved it :
arr.map((x)=>x.complement != null? (x.complement.map((y)=>y.name+' '+y.description)+"") :'');
Having a javascript object, you can go through the keys of the object and combine some of them into strings
It will look something like this:
const jsonObject = [{...}, {...}, ...]
const complements = [];
jsonObject.forEach((item) => {
let complement = item['complement'].reduce((result, currObj)
=> result += (currObj.name+' '+currObj.description), "");
complements.push(complement);
});
This is just an example. There are many ways to do it.

How do you delete an empty array from javascript?

For reference I have zero javascript knowledge or any coding knowledge. I typically just hook up applications via IPASS applications that don't require any coding knowledge. However, I found out I need to inject some javascript into the application in order to avoid an error message.
I have the below JSON record.
I need to get rid of the empty array (sorry... if it is not an array but an object? Like I said, no javascript knowledge).
In the below code essentially what I want is to completely delete this line, because there is nothing inside the brackets and it is causing errors:
"lineitemsdata": []
Full JSON record below for reference
"id": "5399286500",
"properties": {
"state": "AB",
"website": null,
"zip": "T3B5Y9"
},
"createdAt": "2021-02-18T22:13:06.111Z",
"updatedAt": "2021-05-17T14:35:09.540Z",
"archived": false,
"associations": {
"deals": {
"results": [
{
"id": "5230410841",
"type": "company_to_deal"
}
]
}
},
"dealdata": [
{
"id": "5230410841",
"properties": {
"hs_lastmodifieddate": "2021-05-13T14:00:33.101Z",
"hs_object_id": "5230410841",
"hubspot_owner_id": "52200226"
},
"associations": {
"line items": {
"results": [
{
"id": "1468189759",
"type": "deal_to_line_item"
},
{
"id": "1468189760",
"type": "deal_to_line_item",
"lineitemsdata": []
}
]
}
}
}
],
"DealOwner": [
{
"id": "52200226",
"email": "email#email.com",
"firstName": "Bob"
}
],
"NetSuiteCustomerID": 1745
}
Item inside object is called a property. If you (for some reason) have to include the property, but don't want it to have any value you can either set it's value to null or undefined.
I suspect I'm going to get criticized for this, but here is a quick and dirty way of removing this specific problem through string replacement. The 'right' way would be to break down your json into separte objects until you get to the level where the offending object lives, remove it, then rebuild it all back. For what it's worth, here's an alternative to that
let json = {
"id": "5399286500",
"properties": {
"state": "AB",
"website": null,
"zip": "T3B5Y9"
},
"createdAt": "2021-02-18T22:13:06.111Z",
"updatedAt": "2021-05-17T14:35:09.540Z",
"archived": false,
"associations": {
"deals": {
"results": [{
"id": "5230410841",
"type": "company_to_deal"
}]
}
},
"dealdata": [{
"id": "5230410841",
"properties": {
"hs_lastmodifieddate": "2021-05-13T14:00:33.101Z",
"hs_object_id": "5230410841",
"hubspot_owner_id": "52200226"
},
"associations": {
"line items": {
"results": [{
"id": "1468189759",
"type": "deal_to_line_item"
},
{
"id": "1468189760",
"type": "deal_to_line_item",
"lineitemsdata": []
}
]
}
}
}],
"DealOwner": [{
"id": "52200226",
"email": "email#email.com",
"firstName": "Bob"
}],
"NetSuiteCustomerID": 1745
}
json = JSON.stringify(json)
let strstart = json.indexOf('"lineitemsdata":[]');
let commapos = json.lastIndexOf(',', strstart);
json = json.substr(0, commapos) + " " + json.substr(commapos + 1);
json = json.replace('"lineitemsdata":[]', '');
json = JSON.parse(json)
console.log(json)
You can use this to strip any empty lineitems arrays from your json.
Assuming the reference to your record is json
for(dealIdx in json.dealdata) {
for (resultIdx in json.dealdata[dealIdx].associations["line items"].results) {
let lineItemsData = json.dealdata[dealIdx].associations["line items"].results[resultIdx].lineitemsdata
if (lineItemsData != undefined && lineItemsData.length === 0 ) {
delete json.dealdata[dealIdx].associations["line items"].results[resultIdx].lineitemsdata
}
}
}

Need to group data in Object based on value

I am using React/Typescript in my application but need help with basic JavaScript. I am trying to group the data coming from an api call (in this example i'll use mock data) without modifying the actual JSON. I need to group the data based on the 'deviceType' value. So if there are 4 objects, if two are ipad and two are iphone, I need to group those in order. Right now, the mock data is showing Ipad air, then Iphone 6plus, then Ipad air, and then Iphone 6plus again. I need to group these so the new object has the two ipadAir objects first and then the iphone 6plus object coming after. I believe this can be done by making a copy of the old object using spread operator and then modifying it before returning. Here is the data object:
{
"data": {
"DirectvNowDeviceNotifications": [
{
"AccountNumber": "180802190357553",
"AlertDescription": [
{
"AlertType": "BUFFERINGERRORS",
"AlertCode": "CRITICAL_ISFATAL",
"AlertInfo": "ACCOUNT_ALERT",
"SkipDismissal": false,
"DISMISSAL_EXPIRY_DATE": "",
"Content": {
"issueTitle": "Buffering Error Detected",
"issueDescription": "Buffering Error Detected"
},
"AlertAdditionalInfo": [
{
"Name": "reasonCodes",
"Value": "CRITICAL_ISFATAL"
},
{
"Name": "make",
"Value": "APPLE"
},
{
"Name": "deviceType",
"Value": "IPAD AIR"
},
{
"Name": "deviceID",
"Value": "F920BE29-1321-498A-B5D7-7FA84396DE16"
},
{
"Name": "osName",
"Value": "IOS"
},
{
"Name": "ISP",
"Value": "TIME WARNER CABLE INTERNET LLC"
},
{
"Name": "Mobile Carrier",
"Value": "AT&T"
},
{
"Name":"workflowName",
"Value":"CCE_ATTTV_Wifi_Setup"
}
],
"AdditionalContent": {
"longDescription": "You received this error message because the system has captured buffering errors on your device while streaming."
}
},
{
"AlertType": "BUFFERINGERRORS",
"AlertCode": "CRITICAL_FATALV",
"AlertInfo": "ACCOUNT_ALERT",
"SkipDismissal": false,
"DISMISSAL_EXPIRY_DATE": "",
"Content": {
"issueTitle": "Buffering Error Detected",
"issueDescription": "Buffering Error Detected"
},
"AlertAdditionalInfo": [
{
"Name": "reasonCodes",
"Value": "CRITICAL_FATALVIDEOERROR_CT"
},
{
"Name": "make",
"Value": "APPLE"
},
{
"Name": "deviceType",
"Value": "IPHONE 6 PLUS"
},
{
"Name": "deviceID",
"Value": "F920BE29-1321-498A-B5D7-7FA84396DE16"
},
{
"Name": "osName",
"Value": "IOS"
},
{
"Name": "ISP",
"Value": "TIME WARNER CABLE INTERNET LLC"
},
{
"Name": "Mobile Carrier",
"Value": "AT&T"
},
{
"Name":"workflowName",
"Value":"CCE_DTVN_PLAYER_ERRORS"
},
{
"Name":"workflowName",
"Value":"CCE_DTVN_PLAYER_ERRORS"
}
],
"AdditionalContent": {
"longDescription": "You received this error message because the system has captured buffering errors on your device while streaming"
}
},
{
"AlertType": "OSUNSUPPORTED",
"AlertCode": "N_NOT_SUPPORTED",
"AlertInfo": "ACCOUNT_ALERT",
"SkipDismissal": false,
"DISMISSAL_EXPIRY_DATE": "",
"Content": {
"issueTitle": "The device you are trying to use with DIRECTV NOW is not supported.",
"issueDescription": "The device you are trying to use with DIRECTV NOW is not supported."
},
"AlertAdditionalInfo": [
{
"Name": "reasonCodes",
"Value": "VSTB_UNSUPPORTED_DEVICE"
},
{
"Name": "make",
"Value": "APPLE"
},
{
"Name": "deviceType",
"Value": "IPAD AIR"
},
{
"Name": "deviceID",
"Value": "F920BE29-1321-498A-B5D7-7FA84396DE16"
},
{
"Name": "osName",
"Value": "IOS"
},
{
"Name": "ISP",
"Value": "TIME WARNER CABLE INTERNET LLC"
},
{
"Name": "Mobile Carrier",
"Value": "AT&T"
},
{
"Name":"workflowName",
"Value":"CCE_DTVN_PLAYER_ERRORS"
}
],
"AdditionalContent": {
"longDescription": "<a target='_blank' href='https://www.att.com/esupport/article.html#!/directv-now/KM1200941'>Here</a> is a list of supported devices."
}
},
{
"AlertType": "NA",
"AlertCode": "NA",
"AlertInfo": "NA",
"SkipDismissal": false,
"DISMISSAL_EXPIRY_DATE": "",
"Content": {
"issueTitle": "tell me more title",
"issueDescription": "tell me more description"
},
"AlertAdditionalInfo": [
{
"Name": "reasonCodes",
"Value": "NA"
},
{
"Name": "make",
"Value": "APPLE"
},
{
"Name": "deviceType",
"Value": "IPHONE 6 PLUS"
},
{
"Name": "deviceID",
"Value": "FB2468CF-BF73-4DBC-9600-C61553BB759F"
},
{
"Name": "osName",
"Value": "IOS"
},
{
"Name": "ISP",
"Value": "TIME WARNER CABLE INTERNET LLC"
},
{
"Name": "Mobile Carrier",
"Value": "AT&T"
}
],
"AdditionalContent": {
"longDescription": "tell me more long long long description"
}
}
]
}
]
},
"content": {
"code": 200,
"message": "OK"
}
}
Need objects to be grouped based on device type and return a new object with the proper grouping. Please if anyone can help I would greatly appreciate it, I have been struggling with this. Thank you
You could go through the keys of your object, in the following example I assume that you define this as a javascript object, the result will be two objects each with a key corresponding to the type of device
const newGroup = [];
const data = object["data"]["DirectvNowDeviceNotifications"];
(data).forEach((map, index) => {
Object(map['AlertDescription']).forEach((devices) => {
if(typeof devices['AlertAdditionalInfo'] !== 'undefined'){
const deviceType = devices['AlertAdditionalInfo'].find((type) => type.Name ==='deviceType');
if(typeof deviceType.Value !== 'undefined'){
if(typeof newGroup[deviceType.Value] === 'undefined'){
newGroup[deviceType.Value] = [];
}
newGroup[deviceType.Value].push(devices);
}
}
})
});
example working
this code is just an example you should optimize, the idea is to give you an idea of ​​solution

Javascript test for existence of object key in a object with arrays

I need to check if a property in a complex object (nested objects with arrays) exists or not.
I found several posts on this subject, the most visited the one below.
The problem with the provided solution (checkNested function) doesn't work with objects with arrays.
Does anyone have a solution that cover this case as well?
Cheers.
javascript test for existence of nested object key
This the function I tested:
function checkProperty(obj, prop) {
var parts = prop.split('.');
for (var i = 0, l = parts.length; i < l; i++) {
var part = parts[i];
if (obj !== null && typeof obj === "object" && part in obj) {
obj = obj[part];
} else {
return false;
}
}
return true;
}
This is an example of my object:
{
"_msgid": "3ae30deb.af9962",
"topic": "",
"payload": "I am really upset terrible service",
"error": null,
"parts": {
"id": "3ae30deb.af9962",
"type": "array",
"count": 2,
"len": 1,
"index": 0
},
"case_id": "0001",
"features": {
"usage": {
"text_units": 1,
"text_characters": 34,
"features": 7
},
"sentiment": {
"document": {
"score": -0.912124,
"label": "negative"
}
},
"semantic_roles": [{
"subject": {
"text": "I"
},
"sentence": "I am really upset terrible service",
"object": {
"text": "really upset terrible service",
"keywords": [{
"text": "terrible service"
}]
},
"action": {
"verb": {
"text": "be",
"tense": "present"
},
"text": "am",
"normalized": "be"
}
}],
"language": "en",
"keywords": [{
"text": "terrible service",
"sentiment": {
"score": -0.912124
},
"relevance": 0.902721,
"emotion": {
"sadness": 0.462285,
"joy": 0.002207,
"fear": 0.125395,
"disgust": 0.17766,
"anger": 0.575927
}
}],
"entities": [],
"emotion": {
"document": {
"emotion": {
"sadness": 0.462285,
"joy": 0.002207,
"fear": 0.125395,
"disgust": 0.17766,
"anger": 0.575927
}
}
},
"concepts": [],
"categories": [{
"score": 0.99946,
"label": "/health and fitness/disease/headaches and migraines"
}, {
"score": 0.0155692,
"label": "/education/school"
}, {
"score": 0.0141217,
"label": "/family and parenting/children"
}]
}
}
And a failure test:
console.log(checkProperty(msg, 'features.keywords[0].text') ? msg.features.keywords[0].text : "NA");
The checkProperty function you're using doesn't recognize brackets ([ and ]), it only understands dots. So, just give it dots:
checkProperty(msg, 'features.keywords.0.text');

Categories