How to pass data to a JSON array in nodejs? - javascript

i want to pass data from one JSON array to another. My first json array is below:
var data = [{"Commodity":"Apparel and clothing accessories; knitted or crocheted"},{"Commodity":"Fish and crustaceans, molluscs and other aquatic invertebrates"},{"Commodity":"Meat, fish or crustaceans, molluscs or other aquatic invertebrates; preparations thereof"},{"Commodity":"Natural, cultured pearls; precious, semi-precious stones; precious metals, metals clad with precious metal, and articles thereof; imitation jewellery; coin"},{"Commodity":"Sugars and sugar confectionery"}];
I want to pass each of the "Commodity" values to my second JSON array. I tried using a for loop:
var arr = [];
for(let j = 0; j < data.length; j++) {
arr = [{"title":"Select a commodity:","options":[{"label":data[j]['Commodity'],"value":{"input":{"text":data[j]['Commodity']}}}],"description":"","response_type":"option"}];
}
I need each of the "Commodity" values to be filled inside the "label" and "text" property. However on output, only the last "Commodity" - "Sugars and sugar confectionery" is being displayed in the arr.
Any idea would help. Thank you.
UPDATES:
This is how the output looks like but the "Select a commodity" should only be printed out once. This is a response type option from ibm watson assistant.

EDIT :
let arr = {
title: "Select a commodity:",
response_type: "option",
description: "",
options:data.map(element => {
return {
label: element.Commodity,
value: {text: element.Commodity}
}
})
}
console.log(arr);
OUTPUT
{
response_type: "option"
title: "Select a commodity:"
description: ""
options: Array(5)
0: {label: "Apparel and clothing accessories; knitted or crocheted", value: {…}}
1: {label: "Fish and crustaceans, molluscs and other aquatic invertebrates", value: {…}}
2: {label: "Meat, fish or crustaceans, molluscs or other aquatic invertebrates; preparations thereof", value: {…}}
3: {label: "Natural, cultured pearls; precious, semi-precious …, and articles thereof; imitation jewellery; coin", value: {…}}
4: {label: "Sugars and sugar confectionery", value: {…}}
}
The problem is you're actually using the "=" operator, which is re-assigning the value to your array - arr.
Instead of arr = [{...
Try using:
var arr = [];
for(let j = 0; j < data.length; j++) {
arr.push({"title":"Select a commodity:","options":[{"label":data[j]['Commodity'],"value":{"input":{"text":data[j]['Commodity']}}}],"description":"","response_type":"option"});
}

Related

Storing data in empty Array returns empty Array (only in AppScript)

I wrote a simple iterator to loop trough a JSON object and parse the object into a new form.
This works as expected in almost any JS environment. (For example in the console(
However, the function below returns an empty array when executed in AppScript.
returns : [[], [], [], [], []]
This problem seems to be AppScript specific. Before I submit a bug through Google Developer Group I like to understand if this might be an App Script specific and intended behavior.
function parseBQData(/*tableData, request*/) {
var tableData = [["20220301","(none)","(direct)","3","1","1"],["20220301","organic","google","3","1","1"],["20220302","(none)","(direct)","4","2","2"],["20220302","organic","bing","1","1","1"],["20220303","(none)","(direct)","1","1","1"]]
try {
// store the array of dimensions and metrics in a variable called 'fields'
var fields = ["date", "medium", "source", "pageviews", "sessions", "users"]
// create a new empty array to store the parsed data
var newtableData = new Array();
// loop through each row in the tableData
for (var i = 0; i < tableData.length; i++) {
Logger.log(tableData[i]) // This returns: [20220301, (none), (direct), 3, 1, 1], [2022]
// create a new empty array to store the current row
var wrapper = new Array();
// loop through each column in the row
for (var j = 0; j < fields.length; j++) {
wrapper[fields[j]] = tableData[i][j]; /// <-is this not working?
Logger.log("Test Log:")
Logger.log("This is the updated field stored in the wrapper:"+wrapper[fields[j]]) // Returns : "20220301"
Logger.log("Lets check the wrapper if has the date/first value : " + wrapper.date ) // Returns "20220301"
// the wrapper does not dissapear but appears as empty when accessed as in root, the assignment abovew worked and the key value pair is accessible
Logger.log("Wrapper : " + JSON.stringify(wrapper)) // This returns always "Wrapper : []" Stringify is solely used to see that atleast something is returned and the wrapper is accesible
Logger.log("This is the current cell: "+fields[j]+" : "+tableData[i][j]) // This returns : "This is the current cell: date : 20220301" ... This is the current cell: medium : (none)
// So in conclusion All values and Arrays are accessible
// store the column data in the current row array, using the column header as the key
}
// add the current row to the new array of parsed data
newtableData.push(wrapper);
}
// return the new array of parsed data
Logger.log(newtableData) //This returns: "[[], [], [], [], []]""
return newtableData;
// if there is an error parsing the data, print the error to the log
} catch (e) {
Logger.log("Error parsing data")
Logger.log(e)
}
}
#Edit: Added some logging and comments
did not try in App Script but works fine with browser JS console :
var TableData = [["20220301","(none)","(direct)","3","1","1"],["20220301","organic","google","3","1","1"],["20220302","(none)","(direct)","4","2","2"],["20220302","organic","bing","1","1","1"],["20220303","(none)","(direct)","1","1","1"]]
function parseBQData(TableData, request) {
try {
var fields = ["date", "medium", "source", "pageviews", "sessions", "users"];
var newTableData = new Array();
for (var i = 0; i < TableData.length; i++) {
var wrapper = new Array();
for (var j = 0; j < fields.length; j++) {
wrapper[fields[j]] = TableData[i][j];
console.log("Wrapper : " + wrapper)
}
newTableData.push(wrapper);
}
return newTableData;
} catch (e) {
console.log("Error parsing data")
console.log(e)
}
}
parseBQData(TableData, 0);
Logs :
Wrapper :
(5) [Array(0), Array(0), Array(0), Array(0), Array(0)]
0: [date: '20220301', medium: '(none)', source: '(direct)', pageviews: '3', sessions: '1', …]
1: [date: '20220301', medium: 'organic', source: 'google', pageviews: '3', sessions: '1', …]
2: [date: '20220302', medium: '(none)', source: '(direct)', pageviews: '4', sessions: '2', …]
3: [date: '20220302', medium: 'organic', source: 'bing', pageviews: '1', sessions: '1', …]
4: [date: '20220303', medium: '(none)', source: '(direct)', pageviews: '1', sessions: '1', …]
length: 5
So my best guess, check Logger print args types, and maybe Logger.log("Wrapper : ", wrapper); ?
In App Script TableData is defined in the global scope. However the parameter TableData passed to parseBQData is in the function scope. If I try to run your script function parseBQData(TableData, request) including TableData in global scope I get TypeError: Cannot read property 'length' of undefined because TableData is undefined. You can fix this by simply:
function parseBQData(request) {
This is not a bug.
I also found this article JavaScript function parameter and scope
Same output but much simpler
function parseBQData() {
const iA = [["20220301", "(none)", "(direct)", "3", "1", "1"], ["20220301", "organic", "google", "3", "1", "1"], ["20220302", "(none)", "(direct)", "4", "2", "2"], ["20220302", "organic", "bing", "1", "1", "1"], ["20220303", "(none)", "(direct)", "1", "1", "1"]]
const fields = ["date", "medium", "source", "pageviews", "sessions", "users"];
iA.unshift(fields)
Logger.log(JSON.stringify(iA));
}
Execution log
10:25:24 AM Notice Execution started
10:25:25 AM Info [["date","medium","source","pageviews","sessions","users"],["20220301","(none)","(direct)","3","1","1"],["20220301","organic","google","3","1","1"],["20220302","(none)","(direct)","4","2","2"],["20220302","organic","bing","1","1","1"],["20220303","(none)","(direct)","1","1","1"]]
10:25:26 AM Notice Execution completed

Create a subset of data selected on columns in 2d javascript array

Sorry for the basic question and bad lexicon, I am (very) new to javascript. I have an array of data and I would like to create a subset of that data, based on selected columns. The first few rows of my data, for example:
0: {ID: 3607, Name: 'Alamo', Funds: 52933955,
Revenues: 9160109, BAT: 5, …}
1: {ID: 3539, Name: 'Alvin', Funds: 6128147,
Revenues: 964083, BAT: 0, …}
2: {ID: 3540, Name: 'Amarillo', Funds: 12450969,
Revenues: 1716038, BAT: 0, …}
I want to create a new array from columns 0, 1, 2, and 4 (ID, Name, Funds, and BAT). In the code below, toolData is the array created from the original dataset (toolData.json), and tableData is the array I'm trying to create from the selected data. selections contains the column numbers I want to pull into the new array.
var getData = () => axios.get('toolData.json')
.then(res => res.data)
.then(data => {
var toolData = data;
console.log(toolData);
var tableData = [];
var selections = [0,1,2,4];
for (i=0; i < toolData.length; i++)
{
tableData[i] = toolData[i];
for (j=0; selections.length; j++)
{
k = selections[j],
tableData[i][j] = toolData[i][k]
}
}
console.log(tableData);
This particular code snippet doesn't work at all, I'm assuming I've created an infinite loop somehow. If I comment out tableData[i] = toolData[i]; then that problem resolves, but the code still doesn't work. console.log(toolData); gives me what I'm looking for (the full panel of data), but console.log(tableData); gives the error:
javascript.js:42 Uncaught (in promise) TypeError: Cannot set properties of undefined (setting '0')
at javascript.js:42
Ultimately I would like the user to be able to choose the columns they want to include in the new array, but before I can figure that puzzle out I need to solve this one.
Well, it seems from what you're saying is that every index in the array is an object.. arr[0][0]==undefined but arr[0]['ID']==3607
function newSubset(arr,dataToSelect){
//arr is the fetched array, dataToSelect is an array of the keys(like ID,Name...) that you want from the array
return arr.map(obj=>{
var toReturn={} //object that would give each desired key for each part in arr
dataToSelect.forEach(key=>toReturn[key]=obj[key]) //placing wanted keys in toReturn
return toReturn
})
}
//usage
var getData = () => axios.get('toolData.json')
.then(res => res.data)
.then(data => {
var wantedKeys=["ID","Name","Funds","BAT"]
console.log(newSubset(data,wantedKeys))
//rest of your code here
LIVE EXAMPLE
var dataArray=[{ID: 3607, Name: 'Alamo', Funds: 52933955, Revenues: 9160109, BAT: 5}, {ID: 3539, Name: 'Alvin', Funds: 6128147, Revenues: 964083, BAT: 0}, {ID: 3540, Name: 'Amarillo', Funds: 12450969, Revenues: 1716038, BAT: 0}]
function newSubset(arr,dataToSelect){
//arr is the fetched array, dataToSelect is an array of the keys(like ID,Name...) that you want from the array
return arr.map(obj=>{
var toReturn={} //object that would give each desired key for each part in arr
dataToSelect.forEach(key=>toReturn[key]=obj[key]) //placing wanted keys in toReturn
return toReturn
})
}
console.log(newSubset(dataArray,["ID","Name","Funds","BAT"]))
The data is a JSON object. It is not indexed by numbers but rather by names.
It's also recommend to use the built-in map function for this.
const tableData = toolData.map(row => ({
ID: row.ID,
Name: row.Name,
Funds: row.Funds,
BAT: row.BAT
}));
If you want the new toolData array to contain arrays instead of objects, you can instead do:
const tableData = toolData.map(row => [
row.ID,
row.Name,
row.Funds,
row.BAT
]);

Object Array with dates, tallied together for each month

Overview
I need to make a chart in my react project.
Using data from a json (Object Array).
Example json:
[
{recruiter_id: 1, datetime_created: "1/01/2021", name: "Aaron"},
{recruiter_id: 2, datetime_created: "9/01/2021", name: "Bob"},
{recruiter_id: 1, datetime_created: "9/01/2021", name: "Aaron"},
{recruiter_id: 3, datetime_created: "20/01/2021", name: "Jane"}
]
Result object array structure required:
[
{name: name,
recruiter_id: recruiter_id,
week_qty: [0,2,1,0,2,0,0,0,0,0,0,0,0,1,0,0,0,...] },
...]
// week_qty will be an array of 52 to represent each week of the year. It will be a 0 if there was no dates for that week.
Goal
This is what the new object array should look like, if we used the example json.
[
{name: "Aaron", recruiter_id:1, week_qty: [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...]},
{name: "Bob", recruiter_id:2, week_qty: [0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...]},
{name: "Jane", recruiter_id:3, week_qty: [0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...]}
]
What I have
I dont have any working code yet. I am currently working on object[0] to attempt to put the dates into the 52 array. And then after that I will then turn it into a loop to work on each object. Once I have it semi working, I will post it for example.
--- Edit ---
var array = result
var flags = [], output = [], l = array.length, i;
for (i = 0; i < l; i++) {
if (flags[array[i].recruiter_id]) continue;
flags[array[i].recruiter_id] = true;
var temp = {}
temp.Recruiter_id = array[i].recruiter_id
temp.Name = array[i].name
temp.QTY = []
output.push(temp);
}
console.log("output : ", output)
This produces the new object array structure with the id and name filled out.
[
{name: name,
recruiter_id: recruiter_id,
week_qty: [] },
...]
It only has 1 object for each id
Now I need to work on getting the week numbers for the dates and put them into each of those objects.
Question
Any code suggestions on how to get this result?
Side Note
If your curious to know how I then plan on using the new object array to use with my chart.
I will let the user select the week. Lets say week 1.
I will then map through the object array and get the week_qty for index 1 and the name value of the object.
I will store that week_qty and the name in a new new object array.
That new new object array will then look like this
[{name: "Aaron",QTY: 2},{name: "Bob",QTY: 1,]
That will then be passed as the x and y value to the chart.
You can use reduce and increase the week counter after parsing each date and getting the week (using moment.js for that part here)
But you can see Get week of year in JavaScript like in PHP for more details on how to calculate it yourself
const data = [
{recruiter_id: 1, datetime_created: "1/01/2021", name: "Aaron"},
{recruiter_id: 2, datetime_created: "9/01/2021", name: "Bob"},
{recruiter_id: 1, datetime_created: "9/01/2021", name: "Aaron"},
{recruiter_id: 3, datetime_created: "20/01/2021", name: "Jane"}
];
const weekly = data.reduce((acc, item, index, array) => {
const {
recruiter_id,
datetime_created,
name
} = item;
let existing = acc.find(({
recruiter_id: id
}) => id === recruiter_id);
if (!existing) {
existing = {recruiter_id, name, week_qty:Array(52).fill(0)};
acc.push(existing);
}
const week = moment(datetime_created,'D/M/YYYY').week()-1;
existing.week_qty[week]++;
return acc;
}, []);
console.log(JSON.stringify(weekly))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js" integrity="sha512-qTXRIMyZIFb8iQcfjXWCO8+M5Tbc38Qi5WzdPOYZHIlZpzBHG3L3by84BBBOiRGiEb7KKtAOAs5qYdUiZiQNNQ==" crossorigin="anonymous"></script>

How to add key value pair to the json?

I am fetching some json, but i want to add a key value pair to each object inside the array.
What i want is to add a key value pair to each object inside students array
You can do something like this:
var students = [ { city: 'California', company: 'ABC'}, { city: 'LA', company: 'PQR'}, { city: 'Mumbai', company: 'XYZ'}];
students.forEach((obj) => {
obj['email']= 'abc#xyz.com';
console.log(obj);
});
// Final Output
console.log(students);
I would suggest you simply use a for loop for each element in your array and since it's JSON simply specify a new "key = value" inside the current element.
edit : here's an example :
var entreprises = [
{id: 33, uuid: "3d103130-ae0d-11e9-8e6c-dfb1a3a5afce", nom: "test", adresse: "test", ville: "tes" },
{id: 34, uuid: "81524090-ae0d-11e9-8894-2326c7695f11", nom: "test2", adresse: "test2", ville: "test2"}];
for (let i = 0; i < entreprises.length; i++) {
entreprises[i].key = "value";
}
Start by iterating through the students array using either a foreach or standard for loop. This will give you access to each of the students, one by one. Since each of the students is an object, you will have to use either bracket or dot notation to store this new key,value pair. Here is an article that will help you determine which strategy to use for accessing keys and storing key,value pairs: Bracket notation vs Dot notation
Note: If the key you are adding already exists, you will be overriding the previous value.
For loop
for (let i = 0; i < students.length; i++) {
const student = students[i];
student[<key>] = <value>;
}
Foreach
students.forEach(student => {
student[<key>] = <value>;
});

Re-ordering JSON data from jQuery .getJSON()

I'm using $.getJSON to pull some data from an data source and the result comes in as JSON, but it's in this format (as it comes from a table):
result {
0: Array {
0: 'First Name',
1: 'Last Name',
2: 'City',
3: 'State'
}
1: Array {
0: 'John',
1: 'Doe',
2: 'Portland',
3: 'Oregon'
}
2: Array {
0: 'Jane',
1: 'Doe',
2: 'Seattle',
3: 'Washington'
}
}
I need to get that data into something that looks more like this:
Object {
'First Name': 'John', 'Jane'
'Last Name': 'Doe', 'Doe'
'City': 'Portland', 'Seattle'
'State': 'Oregon', 'Washington'
}
I thought that I would just put these into a few $.each() loops but I can't seem to get an object with the first array's values as the keys and the matching values as items in an array assigned to that key. I've tried something like this:
var tmpArray = [];
var labelKeys = [];
$.each(result, function(key, val){
if (key < 1){
$.each(val, function(labelKey, labelVal){
labelKeys.push(labelVal);
}
} else {
for (var i=0; i<labelKeys.length;i++){
tmpArray[labelKeys[i]].push(val[i]);
}
}
}
That doesn't work and I get an undefined error for push().
I can separate all the arrays out into their own arrays and get them out to the console, but I can't figure out how to push data to an object or an array using a key value.
How do I push values to an object so that I can just loop through the arrays and group the objects at the same numbered location and assign it to a key that's at the same location in the first array?
You can't call .push() on tmpArray[labelKeys[i]] because it doesn't exist yet. You need to add that key to the object, before trying to call .push().
// this needs to be an object
// arrays can only have numeric keys
var tmpArray = {};
var labelKeys = [];
$.each(result, function(key, val){
if (key < 1){
$.each(val, function(labelKey, labelVal){
labelKeys.push(labelVal);
// Create an array for this label
tmpArray[labelVal] = [];
});
} else {
for (var i=0; i<labelKeys.length;i++){
tmpArray[labelKeys[i]].push(val[i]);
}
}
});

Categories