Updating Json Value with that of another Json - javascript

I want to update automatically the value of comments_list with the values in the comments JSON object
const tweet = JSON.stringify({"tweet_id":1,"created_at":"2022-06-28","comments_list":[]})
const comments = JSON.stringify({"tweet_id":1,"commenter_id": 2"commenter_first_name":"tito","commenter_username":"tito_lulu"})
The final output should look like this
{"tweet_id":1,"created_at":"2022-06-28","comments_list":[{"commenter_id": 2"commenter_first_name":"tito","commenter_username":"tito_lulu"}]}

I'd work with those strings in an object form, otherwise string-manipulation could be slow in some cases.
This is by no means the fastest solution but perhaps the idea behind it can be helpful.
const tweet = [{
"tweet_id": 1,
"created_at": "2022-06-28",
"comments_list": []
}]; // There could be many tweet objects so wrap it in an array
const comments = [{
"tweet_id": 1,
"commenter_id": 2,
"commenter_first_name": "tito",
"commenter_username": "tito_lulu"
},
{
"tweet_id": 1,
"commenter_id": 5,
"commenter_first_name": "me-too",
"commenter_username": "me294"
}
]; // Same here, could be many comments right?
let UpdatedTweets = [];
// There are faster ways to do this, but for your question
tweet.forEach((tweet, tweetIndex) => {
// Loop each tweet
let post = tweet;
comments.forEach((comment, commentIndex) => {
if (comment.tweet_id == tweet.tweet_id) {
// we have a match lets combine them
tweet.comments_list.push({
commenter_id: comment.comment_id,
commenter_first_name: comment.commenter_first_name,
commenter_username: comment.commenter_username
});
}
});
UpdatedTweets.push(post);
});
console.log(JSON.stringify(UpdatedTweets));

The general idea is:
Parse the JSON into JS objects
Update the target object with the complementary information
Stringify the target object into JSON (only if you need to, eg. send the data to some other machine)
In your case:
const tweet = JSON.stringify({"tweet_id":1,"created_at":"2022-06-28","comments_list":[]});
const comments = JSON.stringify({"tweet_id":1,"commenter_id": 2,
"commenter_first_name":"tito","commenter_username":"tito_lulu"});
let o_tweet = JSON.parse(tweet)
, o_comments = JSON.parse(comments)
;
if (Array.isArray(comments)) { // Test whether that is a single or multiple comments
comments.forEach( c => { o_tweet.comments_list.push(c); });
} else {
o_tweet.comments_list.push(o_comments);
}
console.log(o_tweet);
// Only if needed:
// let newtweet = JSON.stringify(o_tweet)

Related

JavaScript Read data from multidimensional object with dynamic keys [duplicate]

This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Closed 21 days ago.
Background
I have an object like below:
// Data from the database according to their columns and subordinate tables.
const itemData = {
'license_number': '25/2022',
'application': {
'tracking_number': '535345345',
'applicant_name': 'Misir Ali Humayun'
}
};
I know I can read the data from this object like below:
console.log(itemData.licese_number); // '25/2022'
console.log(itemData.application.tracking_number); // '535345345'
// or
console.log(itemData["licese_number"]); // '25/2022'
console.log(itemData.["application"]["tracking_number"]); // '535345345'
Actual Issue
I want to read the data in a dynamic fashion. For example, I have a defined structure like below:
var placeholder = [
{
"find": "%LICENSE%",
"column": "license_number"
},
{
"find": "%APPLICANT%",
"column": "application.applicant_name"
}
];
Now if I have a replacement function:
const replacePlaceholdersWithData = (content) => {
var replacements = {};
// Constructing the object like { "%STRING%" : "DB_VALUE", "%STRING_2%" : "DB_VALUE_2" }
placeholders.filter((object) => replacements[object.find] = itemData[object.column]); // 👈 ISSUE HERE
// #props https://stackoverflow.com/a/7975025/1743124
content = content.replace(/%\w+%/g, function (all) {
return replacements[all] || all;
});
return content;
};
...and a content like below:
const content = "A License numbered %LICENSE% from the %APPLICANT% is received";
console.log(replacePlaceholdersWithData(content));
// Will output: 'A License numbered 25/2022 from the %APPLICANT% is received'
You can guess that the first placeholder (%LICENSE%) will be replaced with '25/2022', but the second one won't be affected, because of the reading style at 👈: itemData["application.applicant_name"] won't match with any real column/key.
QUESTION: How can I resolve that issue?
I know I can use object.column.includes('.') along with object.column.split('.') and get an array of dimensions. But I am clueless, how can I use the array to get data from a multi-dimensional object dynamically?
const itemData = {
'license_number': '25/2022',
'application': {
'tracking_number': '535345345',
'applicant_name': 'Misir Ali Humayun'
}
};
const placeholder = [
{
"find": "%LICENSE%",
"column": "license_number"
},
{
"find": "%APPLICANT%",
"column": "application.applicant_name"
}
];
const content = "A License numbered %LICENSE% from the %APPLICANT% is received";
function replacePlaceholdersWithData(data, content) {
placeholder.forEach(({find, column})=>content = content.replaceAll(find, lookup(data, column)))
return content;
}
function lookup(data, path) {
let [first, ...rest] = path.split('.');
return rest.length ? lookup(data[first], rest.join('.')) : data[path];
}
console.log(replacePlaceholdersWithData(itemData, content));

How can I merge individual object values?

I have the following problem:
I want to read out my table names from a SQL database and then make a comparison as to whether it already exists. I know there is the formula IF EXISTS ... but IF doesn't work .. So here's my previous variant:
First i extracted everything before the filename.csv (C:\Users\Frederic\Desktop\Drag&Drop...) and then the ".csv". Do not be surprised why 51;) The filename is so long
var filename = filePath.slice(51);
var richtigername = filename.replace(".csv","").toString();
console.log(richtigername)
here the result in the console:
for example: fxbewertung
As a second step I let me show the file names:
connection.query('Show tables from datein', function(err, datein) {
let string = JSON.stringify(datein);
let json = JSON.parse(string);
console.log(json)
here the result in the console:
[ { Tables_in_datein: 'fxbewertung' },
{ Tables_in_datein: 'kontoauszug' },
{ Tables_in_datein: 'lsreport' } ]
Furthermore, I extracted the values (name of the SQL tables):
for (var k = 0; k < json.length; k++) {
var werte = Object.values(json[k])
console.log(werte)
};
here the result in the console:
[ 'fxbewertung' ]
[ 'kontoauszug' ]
[ 'lsreport' ]
Now I don't know how i can take the comparison that for example for the file fxbewertung exist a database ('fxbewertung').
My consideration is to somehow browse the individual arrays .. or merge and then browse. At the end should come out true or false
P.S .: it may well be complicated yet but I'm not a real programmer or something;)
Best regards
Frederic
You can use some() method to check if a table exists for that filename.
var tableExists = tables.some(item => item['Tables_in_datein'] === filename);
Live Example:
var tables = [{
Tables_in_datein: 'fxbewertung'
},
{
Tables_in_datein: 'kontoauszug'
},
{
Tables_in_datein: 'lsreport'
}
];
var filename = 'fxbewertung';
var tableExists = tables.some(item => item['Tables_in_datein'] === filename);
if (!tableExists) {
// Table not found for filename.
} else {
// Table found. Do something.
}
Assuming you finished executing your query and stored the data as following:
const queryResult = [ { Tables_in_datein: 'fxbewertung' },
{ Tables_in_datein: 'kontoauszug' },
{ Tables_in_datein: 'lsreport' } ]
You'll then need to map this array to extract the values and store them in a single array like so:
const values = queryResult.map(e=>e[Object.keys(e)[0]]) // ["fxbewertung", "kontoauszug", "lsreport"]
Since you're looking for a true/false result by giving a file name, you'll need to use indexOf to achieve that.
const valueExists = filename => values.indexOf(filename) !== -1
After that execute valueExists with the file name you're looking for:
valueExists("kontoauszug"); // true
valueExists("potato"); // false
Hope this helps!
An efficient solution could be to use Array.prototype.find(). Where it would return from the moment it finds a truthy value and would not iterate till the end (unless the match exists at the end).
Demo Code:
const tablesArr = [
{
Tables_in_datein: "fxbewertung"
},
{
Tables_in_datein: "kontoauszug"
},
{
Tables_in_datein: "lsreport"
}
];
const tabletoFind = "fxbewertung";
const tableFound = tablesArr.find(item => item["Tables_in_datein"] === tabletoFind) ? true: false;
console.log(tableFound);
if(tableFound){
//*yes table found*/
}else{
///*nope table not found*/
}

Preventing duplicate objects from being added to array?

I am building a little shop for a client and storing the information as an array of objects. But I want to ensure that I am not creating "duplicate" objects. I have seen similar solutions, but perhaps it is my "newness" to coding preventing me from getting the gist of them to implement in my own code, so I'd like some advice specific to what I have done.
I have tried putting my code in an if look, and if no "part", my variable looking for part number, exists in the code, then add the part, and could not get it to function.
Here is the function I am working on:
function submitButton(something) {
window.scroll(0, 0);
cartData = ($(this).attr("data").split(','));
arrObj.push({
part: cartData[0],
description: cartData[1]
});
}
arrObj is defined as a global variable, and is what I am working with here, with a "part" and a "description", which is the data I am trying to save from elsewhere and output to my "#cart". I have that part working, I just want to ensure that the user cannot add the same item twice. (or more times.)
Sorry if my code is shoddy or I look ignorant; I am currently a student trying to figure these things out so most of JS and Jquery is completely new to me. Thank you.
You can create a proxy and use Map to hold and access values, something like this
let cart = new Map([{ id: 1, title: "Dog toy" }, { id: 2, title: "Best of Stackoverflow 2018" }].map(v=>[v.id,v]));
let handler = {
set: function(target,prop, value, reciver){
if(target.has(+prop)){
console.log('already available')
} else{
target.set(prop,value)
}
},
get: function(target,prop){
return target.get(prop)
}
}
let proxied = new Proxy(cart, handler)
proxied['1'] = {id:1,title:'Dog toy'}
proxied['3'] = {id:3,title:'Dog toy new value'}
console.log(proxied['3'])
Assuming the 'part' property is unique on every cartData, I did checking only based on it.
function submitButton(something) {
window.scroll(0, 0);
cartData = ($(this).attr("data").split(','));
if(!isDuplicate(cartData))
arrObj.push({
part: cartData[0],
description: cartData[1]
});
}
const isDuplicate = (arr) => {
for(obj of arrObj){
if(arr[0] === obj.part)
return true;
}
return false;
}
If you want to do the checking on both 'part' and 'description' properties, you may replace the if statement with if(arr[0] === obj.part && arr[1] === obj.description).
Thanks everyone for their suggestions. Using this and help from a friend, this is the solution that worked:
function submitButton(something) {
window.scroll(0,0);
cartData = ($(this).attr("data").split(','));
let cartObj = {
part: cartData[0],
description: cartData[1],
quantity: 1
}
match = false
arrObj.forEach(function(cartObject){
if (cartObject.part == cartData[0]) {
match = true;
}
})
console.log(arrObj);
if (!match) {
arrObj.push(cartObj);
}
Okay, you have multiple possible approaches to this. All of them need you to specify some kind of identifier on the items which the user can add. Usually, this is just an ID integer.
So, if you have that integer you can do the following check to make sure it's not in the array of objects:
let cart = [{ id: 1, title: "Dog toy" }, { id: 2, title: "Best of Stackoverflow 2018" }];
function isInCart(id) {
return cart.some(obj => obj.id === id);
}
console.log(isInCart(1));
console.log(isInCart(3));
Another approach is saving the items by their id in an object:
let cart = { 1: { title: "Dog toy" }, 2: { title: "Best of Stackoverflow 2018" } };
function isInCart(id) {
if(cart[id]) return true;
return false;
}
Try to use indexOf to check if the object exists, for example:
var beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];
console.log(beasts.indexOf('aaa'));
// expected output: -1

JAVASCRIPT object to array conversion

I search on stackoverflow before post my question, but I didn't find any solution. I have an object like this :
"{"COURRIERS":
{"05. Juridique":
[{"res_id":100,"type_label":"Plainte","subject":"test23","doctypes_first_level_label":"COURRIERS","doctypes_second_level_label":"05. Juridique","folder_level":2}]
}
}"
And I need to access it like an array, in order to get the information like res_id etc..
How can I do this ?
Thanks in advance
Assuming that you won't have more than one object/array in each layer, this should get you what you need.
let obj = {
"COURRIERS": {
"05. Juridique": [{
"res_id": 100,
"type_label": "Plainte",
"subject": "test23",
"doctypes_first_level_label": "COURRIERS",
"doctypes_second_level_label": "05. Juridique",
"folder_level": 2
}]
}
}
let folder = Object.keys(obj)[0]
let type = Object.keys(obj[folder])[0]
let result = obj[folder][type][0]
console.log(result)
You can gain access to the data in multiple ways. The following below will help clarify some of the way you can access some of the data.
myObj.type = "Dot syntax";
myObj.type = "Dot syntax";
myObj["date created"] = "String with space";
myObj[str] = "String value";
myObj[rand] = "Random Number";
myObj[obj] = "Object";
myObj[""] = "Even an empty string";
For your problem you can use the following
var x = {
"COURRIERS":{
"05. Juridique":[
{
"res_id":100,
"type_label":"Plainte",
"subject":"test23",
"doctypes_first_level_label":"COURRIERS",
"doctypes_second_level_label":"05. Juridique",
"folder_level":2
}
]
}};
console.log(x['COURRIERS']['05. Juridique'][0].res_id)
Something like that ?
(I insert the data inside a variable and print the wanted result with key index)
let obj = {
"COURRIERS":{
"05. Juridique":[
{
"res_id":100,
"type_label":"Plainte",
"subject":"test23",
"doctypes_first_level_label":"COURRIERS",
"doctypes_second_level_label":"05. Juridique",
"folder_level":2
}
]
}
};
console.log(obj["COURRIERS"]["05. Juridique"][0]["res_id"]);
EDIT
You want to acess it with variable.
For avoid bug, I strong recommend you to check if the variable value key exist in the array/object like :
let folder = 'COURRIERS';
if(folder.indexOf(data) >= 0) { // folder.indexOf(data) = 0
// ... finish the job here :)
}
// indexOf return -1 if the value is not found

Populate second array in an object with values from its first array

I have situation like this
const links = {
ALLOWED1: [ 'some_path1' ],
ALLOWED2: [ 'some_path2' ]
}
However I want to also allow paths from previous array on ALLOWED2, I've tried
const links = {
ALLOWED1: [ 'some_path1' ],
ALLOWED2: [ ...links['ALLOWED1'], 'some_path2' ]
}
But this is not valid as links will not defined yet. Of course I can populate it manually, but would rather find a more elegant solution.
You could do it with three lines instead
const links = {};
links.ALLOWED1 = [ 'some_path1' ];
links.ALLOWED2 = [ ...links['ALLOWED1'], 'some_path2' ];
console.log(links.ALLOWED2);
Remember, const only keeps the reference to the object constant, not the object's contents. For that you would need Object.defineProperty
If the contents of allowed1 and allowed2 ever change I might consider using a function to get them both. Like: links.all = () => [...links.ALLOWED1, ...links.ALLOWED2]. To me, that would read clearer in the code, unless it's really clear that allowed2 will always be a superset of allowed1.
If you're not going to change ALLOWED2, you can convert it to a getter:
const links = {
ALLOWED1: [ 'some_path1' ],
get ALLOWED2() { return [ ...this['ALLOWED1'], 'some_path2' ] }
}
console.log(links.ALLOWED2);
An alternative, just because there are many ways to do this and it's mostly a matter of style :)
const links = (() => {
const ALLOWED1 = ["some_path1"],
ALLOWED2 = [...ALLOWED1, "some_path2"];
return { ALLOWED1, ALLOWED2 };
})();
console.log(links);

Categories

Resources