Manipulate values in a JSON in nodeJS [duplicate] - node.js

This question already has answers here:
How to update a value in a json file and save it through node.js
(8 answers)
Closed 2 years ago.
I am new to Nodejs and JSON manipulations. I have a jSON that looks like
"ent": [
{
"employee": [
{
"emp_name": "",
"column": "employee",
"emp_id": 123456,
"first name": "Joe",
"last name": "Bloggs",
"email": "",
"ldapid":
} ,
{
"emp_name": "",
"column": "employee",
"emp_id": 123456,
"first name": "Foo",
"last name": "Bars",
"email": "",
"ldapid":
}
]
}
]
I need to fill the email, ldapid and emp_name based on the firstname and last name
The desired output is
"ent": [
{
"employee": [
{
"emp_name": "Joe Bloggs",
"column": "employee",
"emp_id": 123456,
"first name": "Joe",
"last name": "Bloggs",
"email": "jbloggs#mycompemail.com",
"ldapid": "jbloggs"
} ,
{
"emp_name": "Foo Bars",
"column": "employee",
"emp_id": 567891,
"first name": "Foo",
"last name": "Bars",
"email": "fbars#mycompemail.com",
"ldapid": "fbars"
}
]
}
]
Since I am super new to the nodeJS world , I am making some initial steps to get to where I want..
The following is what I have done..
EDITED my POST
Hi All, Thanks for all your responses.
I was hoping to get an answer that did something similar to the below. this may not be a code with best practices, but does what I want, may be experts in this group can make it better.
const fs = require('fs');
/** Method to start
*
*
*/
const main = async () => {
const myJSONObject = require('./people.json');
try {
for (var i = 0; i < myJSONObject.entities.length; i++) {
var entity = myJSONObject.entities[i];
if (entity.People) {
for (var j = 0; j < entity.People.length; j++) {
var people = entity.People[j];
var fn = people["first name"];
var ln = people["last name"];
var email = `${fn.substring(0, 3)}${ln.substring(0, 5)}#mycompmail.com`;
var ldapid = `${fn.substring(0, 3)}${ln.substring(0, 5)}`;
myJSONObject.entities[i].People[j]["email"] = email.toLowerCase();
myJSONObject.entities[i].People[j]["ldap id"] = ldapid.toLowerCase();
myJSONObject.entities[i].People[j]["preferred first name"] = fn;
myJSONObject.entities[i].People[j]["preferred last name"] = ln;
// console.log(`${fn}.${ln}`)
}
}
}
fs.writeFileSync('./new_people.json', JSON.stringify(myJSONObject, 0, 4));
}
catch (error) {
console.log(error);
}
};
(async () => {
await main();
})();
Any help in this is highly appreciated.
Vakichak

From your code snipped I assume, that the JSON is a string in a file.
So the first step you need to do is to import the file contents into a variable. You can do that with fs.readFileSync(). Now you have the string in a variable.
Next you need to do is to convert the string into an object. You can do that with JSON.parse(). Now you have an object that you can manipulate.
To write it the object back into a file, you can use JSON.stringify() to make it a string again and then fs.writeFileSync() to write it to the file.
Full script:
const jsonString = fs.readFileSync('./people.json')
const jsonObject = JSON.parse(jsonString)
// do stuff with jsonObject that is written into newJsonObject
const newJsonString = JSON.stringify(newJsonObject)
fs.writeFileSync('./new_people.json', newJsonObject)
Note: there's also async functions for writing and reading files. The sync functions are okay if you load a config or something like this at the beginning of a script. If you read/write many files during runtime, you should use the async functions.

Related

Discord.js V12 Sending data from a json file into a single message

I'm making a discord.js v12 bot and a command which lists orders from a json file it sends the json data like this:
is it possible to make to make them in a single embed message?
the command's code:
const fsn = require("fs-nextra");
const Discord = require('discord.js');
module.exports = {
name: 'list',
description: 'List of all orders',
aliases: ['allorders'],
execute(message) {
// List Orders
fsn.readJSON("./orders.json").then((orderDB) => {
for(let x in orderDB) {
const exampleEmbed = new Discord.MessageEmbed()
.setTitle('Here\'s a list of the current orders and their status.')
.setDescription(`\`${x}\`: ${orderDB[x].status}`)
.setTimestamp()
.setFooter(message.member.user.tag, message.author.avatarURL());
message.channel.send(exampleEmbed);
}
});
// Logs in console.
console.log(`${message.author.username} used the list command.`);
}
}
the orders.json has the orders data stored in it like this:
{
"WLL": {
"orderID": "WLL",
"userID": "734532125021307001",
"guildID": "745409671430668389",
"channelID": "746423099871985755",
"order": "a",
"status": "Unclaimed",
"ticketChannelMessageID": "not set"
},
"cwL": {
"orderID": "cwL",
"userID": "734532125021307001",
"guildID": "745409671430668389",
"channelID": "746423099871985755",
"order": "test",
"status": "Unclaimed",
"ticketChannelMessageID": "not set"
},
"bvW": {
"orderID": "bvW",
"userID": "734532125021307001",
"guildID": "745621984192364574",
"channelID": "788863641339428864",
"order": "a",
"status": "Unclaimed",
"ticketChannelMessageID": "not set"
},
}
Yes it is possible, you can do it by moving the send message part outside of the loop, but then inside the loop build up a string...
For example:
fsn.readJSON("./orders.json").then((orderDB) => {
let orderString = "";
for(let x in orderDB) {
orderString = orderString + "`" + x + "`: " + orderDB[x].status + "\n";
// add newline character at the end to display each "order" on a separate line
}
const exampleEmbed = new Discord.MessageEmbed()
.setTitle('Here\'s a list of the current orders and their status.')
.setDescription(orderString)
.setTimestamp()
.setFooter(message.member.user.tag, message.author.avatarURL());
message.channel.send(exampleEmbed);
});

Creating dialogs programmatically from JSON file

I am using the Microsoft Bot Framework with Node.js. I have a config file that looks like the following.
{
"server": {
"port": 3978
},
"dialogs": {
"default": {
"text": "This is some sample text.",
"actions": [
{
"title": "Button 1",
"value": "Action 1"
},
{
"title": "Button 2",
"value": "Action 2"
}
]
},
"hello": {
"text": "hello",
"matches": "^hello$"
},
"asdf": {
"text": "asdf",
"matches": "^asdf$"
},
"goodbye": {
"text": "goodbye",
"matches": "^goodbye$"
}
}
}
I want to use a for loop to read through the dialogs and create them so that they respond with the text value and have the trigger action of the matches value.
For example, the bot responds hello to the input of hello, asdf to the input of asdf, and goodbye to the input of goodbye.
The function I have written in an attempt to solve this looks like this.
var create = function(bot, _config) {
var config = JSON.parse(JSON.stringify(_config));
// Create dialogs from config
var keys = Object.keys(config.dialogs);
for(var i = 0; i < keys.length; i++) {
var dialogName = keys[i];
var dialog = config.dialogs[dialogName];
// Skip over default dialog
if(dialogName == "default") continue;
// Create other dialogs
bot.dialog(dialogName, function(session) {
var text = dialog.text;
session.endDialog(text);
}).triggerAction({
matches: new RegExp(dialog.matches, "i")
});
}
}
When I run this, the bot responds with goodbye to the inputs of hello, asdf, and goodbye. However, the console shows that the correct dialogs are being called when they are supposed to. Even when I call the hello dialog by using session.beginDialog('hello');, the bot returns goodbye.
What seems to be causing the problem here?
It's a common “gotchas” of var in javascript. replace var to let should fix your issue.
The issue similar with
for (var i = 0; i < 10; i++) {
setTimeout(function() { console.log(i); }, 100 * i);
}
The root cause is var is function-scoped and let is block-scoped. You can refer to https://www.typescriptlang.org/docs/handbook/variable-declarations.html for details.

How to remove and update a XML tag in xml2js

How can I edit XML file by xml2js
const fs = require('fs');
const xml2js = require('xml2js');
var fn = 'file.xml';
fs.readFile(fn, function(err, data) {
parser.parseString(data, function(err, result) {
//result.data[3].removeChild(); ?????
//result.date[2].name.innerText = 'Raya'; ?????
});
});
This is not working!
To remove a property from a JavaScript object, simply set the property to undefined:
result.name = undefined;
Result from xml2js:
{
"name": "I will get deleted",
"items": [
{
"itemName": "Item 1",
"itemLocation": "item1.htm"
},
{
"itemName": "Item 2",
"itemLocation": "item2.htm",
}
]
}
After setting to undefined:
{
"items": [
{
"itemName": "Item 1",
"itemLocation": "item1.htm"
},
{
"itemName": "Item 2",
"itemLocation": "item2.htm",
}
]
}
For you, this would be
result.data[3] == undefined;
Tip: you can use JSON.stringify to help you.

Populating a parameter using arrays - Beginner

I am stuck with this issue for a few days now. I am not able to format the values according to the given format.
I have 2 Array objects.
var name = ["sam","Anthony"];
var age = ["4","10"];
The name and age array may contain more values in it. So it means that the 2 arrays above are dynamic.
I need to extract values from these arrays and add them in the Item section as shown in the following code. However, I am not able to hardcode the array content as this array is dynamic in size. It may contain more student records in it. In that case How am I able to construct the following params variable after populating the values of the name and age arrays ?
var params = {
RequestItems: {
"Student": [
{
PutRequest: {
Item: {
"name": "sam",
"age": "4"
}
}
},
{
PutRequest: {
Item: {
"name": "Anthony",
"age": "10"
}
}
}
]
}
};
Use the map function:
var names = ["sam", "Anthony"];
var age = ["4", "10"];
var params = {
RequestItems: {
"Student": names.map(function(c, index) {
return {
PutRequest: {
Item: {
"name": c,
"age": age[index]
}
}
};
})
}
};
alert(JSON.stringify(params, null, 4));

DynamoDB putitem in NodeJs - arrays of objects

I'm trying to set up a small api from AWS Lambda to DynamoDB and I am having trouble figuring out if and how I can write an array of objects into a key.
I have an object like
{
"teamName": "Team Awesome",
"members": [
{
"email": "person-1#example.com",
"name": "Bob"
},
{
"email": "person-2#example.com",
"name": "Alice"
}
]
}
The members array is giving me issues, in the docs it looks like it can be done considering the list types, but there is just no example how HOW to do it, and I am running out of ways to try it.
So is it possible to write something in this format at all and how do you in that case do it?
Example code - what do I put at ???
var AWS = require('aws-sdk');
var dynamodb = new AWS.DynamoDB();
exports.handler = function(event, context) {
var tableName = "GDCCompetition";
var datetime = new Date().getTime().toString();
DynamoDB.putItem({
"TableName": tableName,
"Item": {
"datetime": {
"N": datetime
},
"teamName": {
"S": event.teamName
},
"members": ???
}
});
}
The documentation is not really obvious, but there is a thing called DocClient, you can pass a usual JS object to it and it will do all the parsing and transformation into AWS object (with all the types). You can use it like this:
var AWS = require("aws-sdk");
var DynamoDB = new AWS.DynamoDB.DocumentClient();
var params = {
TableName: "MyTable",
Item: {
"teamName": "Team Awesome",
"members": [
{
"email": "person-1#example.com",
"name": "Bob"
},
{
"email": "person-2#example.com",
"name": "Alice"
}
]
}
};
DynamoDB.put(params, function (err) {
if (err) {
return throw err;
}
//this is put
});
You could convert the object to DynamoDb record first
const AWS = require('aws-sdk');
var tableName = "GDCCompetition";
var datetime = new Date().getTime().toString();
const members = [
{
"email": "person-1#example.com",
"name": "Bob"
},
{
"email": "person-2#example.com",
"name": "Alice"
}
];
const marshalled = AWS.DynamoDB.Converter.marshall({ members });
const params = {
"TableName": tableName,
"Item": {
"datetime": {
"N": datetime
},
"teamName": {
"S": event.teamName
},
"members": marshalled.members,
},
}
AWS.DynamoDB.putItem(params, function (err) {
if (err) {
return throw err;
}
});

Resources