Restrucutre JSON data - javascript

I'm fetching data from an API and I'm trying to restucture the data. I want the data te be structed in a type of JSON way. Like shown below.
I have tried alot but I find it very hard to do because for each methode and the for loops used.
How can I go about doing this? Any help would be greatly appricated!
I want to make and change the output of the program to this type of json structure:
[
{ id: 'bitcoin',
x: [1571695345012, 1571699061041, 1571702676146, 1571706278232, 1571709762429],
y: [8222.065325961827, 8192.012381921422, 8220.91853113097, 8192.5487839435, 8184.743590188011]
}
{ id: 'ethereum',
x: [1571695472168, 1571699049447, 1571702639502, 1571706279834, 571709827389],
y: [174.5266477952419, 173.6409574561425, 174.35449608806442, 173.9800501560514, 173.99298281578433]
}
{ id: 'ripple',
x: [1571695472168, 1571699049447, 1571702639502, 1571706279834, 571709827389],
y: [0.2926270710439499, 0.29225262544982944, 0.2922858993183195, 0.29169629356590593, 0.2926150467160304]
}
]
This is the output I go right now:
[ { id: 'bitcoin' },
{ x: 1571695345012 },
{ x: 1571699061041 },
{ x: 1571702676146 },
{ x: 1571706278232 },
{ x: 1571709762429 },
{ y: 8222.065325961827 },
{ y: 8192.012381921422 },
{ y: 8220.91853113097 },
{ y: 8192.5487839435 },
{ y: 8184.743590188011 },
{ id: 'ethereum' },
{ x: 1571695472168 },
{ x: 1571699049447 },
{ x: 1571702639502 },
{ x: 1571706279834 },
{ x: 1571709827389 },
{ y: 174.5266477952419 },
{ y: 173.6409574561425 },
{ y: 174.35449608806442 },
{ y: 173.9800501560514 },
{ y: 173.99298281578433 },
{ id: 'ripple' },
{ x: 1571695366383 },
{ x: 1571699042366 },
{ x: 1571702671612 },
{ x: 1571706274116 },
{ x: 1571709875603 },
{ y: 0.2926270710439499 },
{ y: 0.29225262544982944 },
{ y: 0.2922858993183195 },
{ y: 0.29169629356590593 },
{ y: 0.2926150467160304 } ]
The code used:
//Initialize unirest
var unirest = require("unirest");
//Combined array
var JSONApiData = ['bitcoin', 'ethereum', 'ripple'];
var ApiSparkline = []; // *** Should this really be a module global??
function unirestp(...args) {
return new Promise((resolve, reject) => {
unirest(...args).end(res => {
if (res.error) {
reject(res.error);
} else {
resolve(res.body);
}
});
});
}
async function request() {
console.log("waiting for the sparkline data...");
// Runs the API requests in parallel
const data = await Promise.all(JSONApiData.map(id =>
unirestp("GET", `https://api.coingecko.com/api/v3/coins/${id}/market_chart?vs_currency=usd&days=7`)
));
// Promise.all guarantees that the result array is in the same order as the input array, so
// we can rely on that when mapping the reults
data.forEach((id, index) => {
const {prices} = data[index];
ApiSparkline.push({id: JSONApiData[index]});
for (let j = 0; j < 5; ++j) { // *** What if `prices` doesn't have 5 entries?
ApiSparkline.push({x:prices[j][0]});
}
for (let j = 0; j < 5; ++j) { // *** What if `prices` doesn't have 5 entries?
ApiSparkline.push( {y:prices[j][1]});
}
});
// Show object
console.log(ApiSparkline);
}
//Call request function
request()
.then(() => {
// Done
})
.catch(error => {
console.log(error)
// Handle/report error
});

You would only want to call ApiSparkline.push once per API call (ie forEach)
//Initialize unirest
const unirest = require("unirest");
//Combined array
const JSONApiData = ['bitcoin', 'ethereum', 'ripple'];
function unirestp(...args) {
return new Promise((resolve, reject) => {
unirest(...args).end(res => {
if (res.error) {
reject(res.error);
} else {
resolve(res.body);
}
});
});
}
async function request() {
console.log("waiting for the sparkline data...");
// Runs the API requests in parallel
const data = await Promise.all(JSONApiData.map(id =>
unirestp("GET", `https://api.coingecko.com/api/v3/coins/${id}/market_chart?vs_currency=usd&days=7`)
));
// Promise.all guarantees that the result array is in the same order as the input array, so
// we can rely on that when mapping the reults
const ApiSparkline = [];
data.forEach((result, index) => {
const { prices } = result;
const id = JSONApiData[index];
const x = prices.map(([xItem, yItem]) => xItem);
const y = prices.map(([xItem, yItem]) => yItem);
ApiSparkline.push({
id,
x,
y
});
});
return ApiSparkline;
}
//Call request function
request()
.then(ApiSparkline => {
console.log(ApiSparkline);
})
.catch(error => {
console.log(error)
// Handle/report error
});

Related

how to convert an object to array of objects

I have data in the following format
const data =
{
"sent_total":429,
"sent_distribution":[
{
"date_triggered__date":"2022-12-07",
"count":92
},
{
"date_triggered__date":"2022-12-08",
"count":337
}
],
"delivered":428,
"delivered_distribution":[
{
"timestamp__date":"2022-12-07",
"count":91
},
{
"timestamp__date":"2022-12-08",
"count":337
}
],
}
Need help in converting this in the following format which separates the data by the key (which is sent or delivered) to an array of objects.
const data = [
{
key: sent,
value: 429,
distribution: [
{
date_triggered__date: "2022-12-07",
count: 92,
},
{
date_triggered__date: "2022-12-08",
count: 337,
},
],
},
];
Hope it helps:
const data =
{
"sent_total":429,
"sent_distribution":[
{
"date_triggered__date":"2022-12-07",
"count":92
},
{
"date_triggered__date":"2022-12-08",
"count":337
}
],
"delivered":428,
"delivered_distribution":[
{
"timestamp__date":"2022-12-07",
"count":91
},
{
"timestamp__date":"2022-12-08",
"count":337
}
],
}
const result = [];
Object.keys(data).map((key) => {
const newKey = key.split("_")[0];
let index = result.findIndex((resultItem) => resultItem.key === newKey);
const value = key.includes("_distribution") ? null : data[key];
const distribution = key.includes("_distribution") ? data[key] : null;
if(index === -1) {
result.push({
key: newKey,
value: value,
distribution: distribution
});
} else {
if(value)
result[index].value = value;
if(distribution)
result[index].distribution = distribution;
}
});
console.log(result);

I got error in react while using normal javascript

i am working on react-flow, and my task is to transform the following data => `
`const configObj = {
name: "Dataset",
nodeChild: {
type: "schema",
nodeConfiguration: {
sid1: {
name: "Schema 1",
nodeChild: {
type: "dashboard",
nodeConfiguration: {
did1: {
name: "Dashboard 1"
}
}
}
},
sid2: {
name: "Schema 2",
nodeChild: {
type: "dashboard",
nodeConfiguration: {
did2: {
name: "Dashboard s1",
},
did3: {
name: "Dashboard 3"
}
}
}
}
}
}
}` to this ->
const elements = [
{
id: '1',
type: 'input', // input node
data: { label: 'Input Node' },
position: { x: 250, y: 25 },
},
// default node
{
id: '2',
// you can also pass a React component as a label
data: { label: <div>Default Node</div> },
position: { x: 100, y: 125 },
},
{
id: '3',
type: 'output', // output node
data: { label: 'Output Node' },
position: { x: 250, y: 250 },
},
// animated edge
{ id: 'e1-2', source: '1', target: '2', animated: true },
{ id: 'e2-3', source: '2', target: '3' },
];
`
not exactly but according to data1 so i prepare a code for it and it is working well in node environment but the moment i try it on react it shows some errorenter image description here here is my code
const configObj = {
name: "Dataset",
onClick: true,
nodeChild: {
type: "schema",
nodeConfiguration: {
sid1: {
name: "Schema 1",
nodeChild: {
type: "dashboard",
nodeConfiguration: {
did1: {
name: "Dashboard 1"
}
}
}
},
sid2: {
name: "Schema 2",
nodeChild: {
type: "dashboard",
nodeConfiguration: {
did2: {
name: "Dashboard s1",
nodeChild: {
type: "ritik",
nodeConfiguration: {
ri1: {
name: "Ritik",
}
}
}
},
did3: {
name: "Dashboard 3"
}
}
}
}
}
},
}
let count =1;
let dataConfig = []
const recursion = (obj, level,type) => {
let objData = {}
for(let j in obj){
if(j !== 'nodeChild' && j !== 'nodeParent'){
if(j === 'name'){
objData= {
...objData,
label: obj[j]
}
}else {
objData= {
...objData,
[j]: obj[j]
}
}
}
}
let idd = count
dataConfig = [...dataConfig, {id: count, data: objData, type, level, parentID}]
count++;
if('nodeChild' in obj){
const {nodeConfiguration, type} = obj.nodeChild
for(let val in nodeConfiguration){
recursion(nodeConfiguration[val], level+1, type, parentID = idd)
}
}
if('nodeParent' in obj){
const {nodeConfiguration, type} = obj.nodeParent
for(let val in nodeConfiguration){
recursion(nodeConfiguration[val], level-1, type)
}
}
}
recursion(configObj, level=0, type='root', parentID=1)
let edges = []
for(let i=1; i<dataConfig.length; i++){
let e = {
id: `e${dataConfig[i].id}-${dataConfig[i].parentID}`,
source: `${dataConfig[i].parentID}`, target: `${dataConfig[i].id}`, animated: true
}
edges = [
...edges,
e
]
}
let finalDataSet = []
let x=650, y=25;
let flag = false;
for(let i in dataConfig){
let element = {}
for(let key in dataConfig[i]){
if(key !== 'parentID'){
if(key === 'type'){
let k = dataConfig[i][key]
if(k === 'schema' || k === 'root'){
element = {
...element,
[key]: 'input'
}
}else {
element = {
...element,
[key]: 'output'
}
}
}else {
element = {
...element,
[key]: dataConfig[i][key]
}
}
}
}
element = {
...element,
position: { x, y }
}
// console.log(i)
finalDataSet = [
...finalDataSet,
element
]
y += 75;
if(!flag){
x = 25;
}
x = flag ? x+155 : x
flag = true
}
for(let i =0; i<edges.length; i++){
finalDataSet = [
...finalDataSet,
edges[i]
]
}
const DataSET = finalDataSet
export default DataSET
this code is perfectly working on local nodejs but the same code pops errors on react.js can any one help me on this
It's the recursion(configObj, level=0, type='root', parentID=1) calls that are causing trouble. You think that level=0 is saying to pass 0 to the level parameter but javascript doesn't recognize that syntax. It thinks that level is some variable you forgot to define. Hence the is not defined error.
To fix the issue, just do something like recursion(configObj, 0, 'root', 1) instead.

Restructure JavaScript object into array of objects with named keys

I have the following JavaScript object:
const groupedData = {
"1":[
{"x":"2021-02-05","y":1},
{"x":"2021-02-05","y":1},
{"x":"2021-02-06","y":1}
],
"2":[
{"x":"2021-02-05","y":1},
{"x":"2021-02-06","y":1},
{"x":"2021-02-07","y":1},
{"x":"2021-02-07","y":1},
{"x":"2021-02-07","y":1},
{"x":"2021-02-08","y":1}
]
}
I'd like to group the objects in each of the arrays by x and sum by y and shape the data into a slightly different structure so it can be consumed by a charting library. I have the following function which does the grouping and summing successfully:
const formattedData = [];
Object.keys(groupedData).map((key) => {
var totals = groupedData[key].reduce(function (r, o) {
(r[o.x]) ? r[o.x] += o.y : r[o.x] = o.y;
return r;
}, {});
formattedData.push({ 'name': key, 'data': totals })
});
This outputs the following:
[
{
"name":"1",
"data": {
"2021-02-05":2,
"2021-02-06":1
}
},
{
"name":"2",
"data": {
"2021-02-05":1,
"2021-02-06":1,
"2021-02-07":3,
"2021-02-08":1
}
}
]
However, I'd like the data to be in the following format:
[
{
"name":"1",
"data":[
{"x":"2021-02-05","y":2},
{"x":"2021-02-06","y":1}
]
},
{
"name":"2",
"data":[
{"x":"2021-02-05","y":1},
{"x":"2021-02-06","y":1},
{"x":"2021-02-07","y":3},
{"x":"2021-02-08","y":1}
]
}
]
I'm struggling to come up with a neat way to do this final part of the formatting. Could anyone advise how to modify the formatting function to implement this last step, in a neat way?
Many thanks
You could map the entries of the object and group the values.
const
data = { 1: [{ x: "2021-02-05", y: 1 }, { x: "2021-02-05", y: 1 }, { x: "2021-02-06", y: 1 }], 2: [{ x: "2021-02-05", y: 1 }, { x: "2021-02-06", y: 1 }, { x: "2021-02-07", y: 1 }, { x: "2021-02-07", y: 1 }, { x: "2021-02-07", y: 1 }, { x: "2021-02-08", y: 1 }] },
result = Object.entries(data).map(([name, data]) => ({
name,
data: Object.values(data.reduce((r, { x, y }) => {
r[x] ??= { x, y: 0 };
r[x].y += y;
return r;
}, {}))
}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Creating 3 worksheets in one workbook (Excel-JS) problem

I need a create an one excel file with 3 worksheets. For now I wrote a function which create worksheet and workbook. I have problem because I need write data into workshet in some executed async function. Maybe some code will describe what I have to do.
var Excel = require('exceljs');
const workbook = new Excel.Workbook({
useStyles: true
})
const headers = [
{ header: 'Plik', key: 'path', width: 40 },
{ header: 'Zwierze', key: 'name', width: 12 },
{ header: 'Prawdopodobienstwo(%)', key: 'confidence', width: 24 },
{ header: 'Czas odpowiedzi(s)', key: 'responseTime', width: 20 }
];
workbook.xlsx.writeFile("./excel/Wyniki.xlsx");
setWorkSheet = (name, responses, filename) => {
workbook.xlsx.readFile(filename)
.then(function () {
const worksheet = workbook.addWorksheet(name);
worksheet.columns = headers;
for (let i = 0; i < responses.length; i++) {
worksheet.addRow(responses[i]);
}
worksheet.getRow(1).style.font = { size: 12, name: 'Bahnschrift SemiBold SemiConden' }
worksheet.getRow(1).eachCell((cell) => {
cell.fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: '993399' }
},
cell.style.font = {
color: {
argb: 'ffffff'
},
size: 14,
}
})
worksheet.eachRow((Row, rowNumber) => {
Row.alignment = {
horizontal: 'center',
}
Row.eachCell((Cell, cellNumber) => {
Cell.alignment = {
vertical: 'middle',
horizontal: 'center'
},
Cell.border = {
top: { style: 'double', color: { argb: 'black' } },
left: { style: 'double', color: { argb: 'black' } },
bottom: { style: 'double', color: { argb: 'black' } },
right: { style: 'double', color: { argb: 'black' } }
}
})
})
worksheet.views = [
{ state: 'frozen', xSplit: 1, ySplit: 1, activeCell: 'B2' },
];
return workbook.xlsx.writeFile(`${filename}`)
})
.then(function () {
console.log("Done");
})
.catch(function (err) {
console.log(err)
});
}
And this function for now create a new file with special defined name worksheet. I need execute this function 3 times and after this operations I need to have one file and 3 worksheets. Here are places where I executed this function:
async function Cognitive() {
let tab = [];
for (let i = 0; i < arrayOfFiles.length; i++) {
let x = await cognitive.cognitiveDetectLabels(arrayOfFiles[i]);
tab.push(x)
}
setWorkSheet('Cognitive', tab, "./excel/Wyniki.xlsx");
}
exports.Cognitive = Cognitive;
async function Rekognition() {
let tab = [];
const path = "./csv/Rekognition.csv";
for (let i = 0; i < arrayOfFiles.length; i++) {
let x = await rekognitionFile.callaws(arrayOfFiles[i]);
tab.push(x)
}
setWorkSheet("Rekognition", tab, "./excel/Wyniki.xlsx");
}
exports.Rekognition = Rekognition;
async function Vision() {
let tab = [];
for (let i = 0; i < arrayOfFiles.length; i++) {
let x = await vision.callVision(arrayOfFiles[i]);
tab.push(x)
}
setWorkSheet("Vision", tab, "./excel/Wyniki.xlsx");
}
exports.Vision = Vision;
When I execute one of this async function. File with worksheet always is overwritten.
However, I need to add sheets to one file (3 sheets). Anyone have some ideas about this problem ? Thank you

Trying to change/match JSON object

I figure I shouldn't be having trouble with this, but I am. I am trying to switch up the syntax/variables of a JSON object to match a certain parameters.
Here is the JSON I am working with:
{
"name":"BHPhotovideo",
"prices":[
{
"price":"799.00",
"createdAt":"2017-07-23T16:17:11.000Z",
"updatedAt":"2017-07-23T17:21:41.000Z"
},
{
"price":"770.00",
"createdAt":"2017-07-21T16:17:11.000Z",
"updatedAt":"2017-07-23T16:17:11.000Z"
},
{
"price":"599.00",
"createdAt":"2017-07-19T16:17:11.000Z",
"updatedAt":"2017-07-22T16:17:11.000Z"
},
{
"price":"920.00",
"createdAt":"2017-07-22T16:17:11.000Z",
"updatedAt":"2017-07-22T16:17:11.000Z"
}
]
},
etc...
I am just trying to get the data to be formatted like this:
{
"label":"BHPhotoVideo", // Same as name
"data":[
{
"x":"2017-07-23T16:17:11.000Z", // Same as createdAt
"y":799 // Same as price
},
{
"x":"2017-07-21T16:17:11.000Z",
"y":770
},
{
"x":"2017-07-19T16:17:11.000Z",
"y":599
},
{
"x":"2017-07-22T16:17:11.000Z",
"y":920
}
]
},
etc...
The amount of these objects are dynamic/subject to change, I've been making a mess out of foreach loops and trying to piece this together. I keep coming into errors, what's the best way to approach this?
What about this ?
data.map(
(item) => ({
"label":"BHPhotoVideo", // Same as name
"data": item.prices.map(nested => ( {
"x":nested.createdAt,
"y":nested.price
}))
})
)
Did you want the y values to be integers?
var ar = [
{
"name":"BHPhotovideo",
"prices":[
{
"price":"799.00",
"createdAt":"2017-07-23T16:17:11.000Z",
"updatedAt":"2017-07-23T17:21:41.000Z"
},
{
"price":"770.00",
"createdAt":"2017-07-21T16:17:11.000Z",
"updatedAt":"2017-07-23T16:17:11.000Z"
},
{
"price":"599.00",
"createdAt":"2017-07-19T16:17:11.000Z",
"updatedAt":"2017-07-22T16:17:11.000Z"
},
{
"price":"920.00",
"createdAt":"2017-07-22T16:17:11.000Z",
"updatedAt":"2017-07-22T16:17:11.000Z"
}
]
},
{
"name":"Adorama",
"prices":[
{
"price":"799.00",
"createdAt":"2017-07-22T16:17:11.000Z",
"updatedAt":"2017-07-23T17:21:41.000Z"
},
{
"price":"799.00",
"createdAt":"2017-07-20T16:17:11.000Z",
"updatedAt":"2017-07-23T16:17:11.000Z"
},
{
"price":"810.00",
"createdAt":"2017-07-18T16:17:11.000Z",
"updatedAt":"2017-07-22T16:17:11.000Z"
},
{
"price":"799.00",
"createdAt":"2017-07-17T16:17:11.000Z",
"updatedAt":"2017-07-22T16:17:11.000Z"
}
]
}
];
var out = ar.map( function(a) {
return {
"label" : a.name,
"prices" : a.prices.map( function(aa) { return {x: aa.createdAt, y: aa.price} })
}
});
console.log( out );
map over the original array returning a changed object; returning the name, and a new array from using map over the prices.
const obj2 = obj.map((item) => {
return {
label: item.name,
data: item.prices.map((data) => {
return {
x: data.createdAt,
y: data.price
}
})
}
});
DEMO

Categories