Accessing json returning undefined react js - json

I am trying to grab some json data to display in Ui but when I iterate over it using the map method I keep getting undefined.Any help will be really appreciated.Here is a link on code sandbox https://codesandbox.io/s/late-wood-kx8w2?file=/src/App.js

This line
const [items, setItem] = useState(Object.keys(trees));
is passing the tree keys to the View function and not the actual data. I believe that you meant to pass the data. Your code passes 'name' and 'children' as {items} that then gets displayed by View.js.
The following code shows you how you can parse the tree and get the names and the values. It's incomplete, but it should give you a start on how to do the traversal.
import React, { useState } from "react";
export default function Start(){
const trees = {
name: "root",
children: [
{
name: "child1",
children: [
{ name: "child1-child1", data: "c1-c1 Hello" },
{ name: "child1-child2", data: "c1-c2 JS" }
]
},
{ name: "child2", data: "c2 World" }
]
};
const treesCopy = trees;
function Traverse(tree){
var treesCopy = tree;
var str = [];
for (var prop in treesCopy) {
console.log(prop);
if (prop=="children"){
str = str + "name: "+ prop + ",";
treesCopy = treesCopy[prop][0];
// console.log('New tree: ',treesCopy);
return str + Traverse(treesCopy);
}
str = str + "name: "+ prop +" value: " + treesCopy[prop]+",";
}
return str;
};
const str = Traverse(treesCopy);
return(
<>
{
str ? str.split(",").map(place => <p> {place} </p>)
: ""
}
</>
)
}

Related

google sheet App script string length function typeerror

function myFunction(input_data)
{
const myJSON = JSON.stringify(input_data);
const myJSON1 = JSON.parse(myJSON);
const data = myJSON1["data"];
const input = JSON.stringify(myJSON1.data);
var result="";
//return typeof input;
for(var i=1;i<input.length-1;i++){
//Logger.log(input[i]);
result += input[i];
}
Logger.log(result);
const obj_result = JSON.parse(result);
const code_status = obj_result.code;
Logger.log(code_status);
result_details= JSON.stringify(obj_result.details);
obj_result_details = JSON.parse(result_details);
Logger.log(obj_result_details.id);
return obj_result_details.id;
}
input_data = {"data":[{"code":"SUCCESS","details":{"Modified_Time":"2022-08-
12T18:30:42+05:30","Modified_By":{"name":"",
"id":"8"},"Created_Time":"2022-08-
12T18:30:42+05:30","id":"87956000","Created_By":{"name":"dev"
,"id":"8"}},"message":"record added","status":"success"}]};
Logger.log(myFunction(input_data));
Error: TypeError: cann't read property length at line no 9.
(this error I am getting in sheet but not in script editor).
As a guess. If you meant to get an array of IDs from the input_data it can be done this way:
var input_data = {
data: [
{
code: "SUCCESS",
details: {
Modified_Time: "2022-08-12T18:30:42+05:30",
Modified_By: { name: "", id: "8" },
Created_Time: "2022-08-12T18:30:42+05:30",
id: "87956000",
Created_By: { name: "dev", id: "8" },
},
message: "record added",
status: "success",
},
],
};
function myFunction(input_data) {
return input_data.data.map(x => x.details.id);
}
console.log(myFunction(input_data)); // output: [ '87956000' ]

How to load json from file and set it as global variable in Vue?

I'm new to Vue. I want to read employeeId from a login form and ust it to load some json files named according as employeeId.json like (10000001.json, 20000001.json) and set the json object as a global variable so I can easily access it in all components.
Firstly, I don't know how to dynamically load json files. Using import sees not work. Some one suggested using require should work. But there are not many examples, I don't know where to put require...
Secondly, how do I set the json as global after the employeeId props in? I'm very confused where to put it (inside the export default or not? inside methods or not? or inside created/mounted or not?) and where to use this or not...
This is the script section of my headerNav.vue file.
<script>
//**I placed them here now, it works, but employeeId is hard coded...
import json10000001 from "./json/10000001.json";
import json20000001 from "./json/20000001.json";
import json30000001 from "./json/30000001.json";
// var employeeId = employeeIdFromLogin;
var jsonForGlobal;
var employeeId = 10000001;
var jsonFileCurrentObj;
if (employeeId == "10000001") {
jsonForGlobal = jsonFileCurrentObj = json10000001;
} else if (employeeId == "20000001") {
jsonForGlobal = jsonFileCurrentObj = json20000001;
} else if (employeeId == "30000001") {
jsonForGlobal = jsonFileCurrentObj = json30000001;
}
export default {
// props:{
// employeeIdFromLogin: String,
// },
props:['employeeIdFromLogin'],
jsonForGlobal,
// employeeIdFromLogin,
data() {
return {
docked: false,
open: false,
position: "left",
userinfo: {},
jsonFileCurrent: jsonFileCurrentObj,
// employeeIdFromLogin: this.GLOBAL3.employeeIdFromLogin
// jsonFile: currentJsonFile
};
},
mounted() {
//**I tried put it here, not working well...
// var employeeId = this.employeeIdFromLogin;
// // var jsonForGlobal;
// console.log("headernav.employeeIdFromLogin="+this.employeeIdFromLogin);
// // var employeeId = 10000001;
// var jsonFileCurrentObj;
// if (employeeId == "10000001") {
// this.jsonForGlobal = this.jsonFileCurrentObj = json10000001;
// } else if (employeeId == "20000001") {
// this.jsonForGlobal = this.jsonFileCurrentObj = json20000001;
// } else if (employeeId == "30000001") {
// this.jsonForGlobal = this.jsonFileCurrentObj = json30000001;
// }
},
methods: {
switchPage(pageName) {
this.$emit("switchPage", pageName);
}
//**I don't know how to use the require...
// var employeeId = 10000001;
// getJsonFile(employeeId) {
// this.currentJsonFile = require("../assets/json/" + employeeId + ".json");
// }
}
};
You might want to use vuex to manage global store. But if you don't want includes Vuex, there is a simpler way to have global state:
Define globalStore.js
// globalStore.js
export const globalStore = new Vue({
data: {
jsonForGlobal: null
}
})
then import it and use in component:
import {globalStore} from './globalStore.js'
export default {
props: ['employeeIdFromLogin'],
data: function ()
return {
jsonLocal: globalStore.jsonForGlobal,
jsonFileCurrent: null
}
},
watch: {
employeeIdFromLogin: {
handler(newVal, oldVal) {
const data = require('./json/' + this.employeeIdFromLogin + '.json')
this.jsonFileCurrent = data
globalStore.jsonForGlobal = data
}
}
}
}

Transform Request to Autoquery friendly

We are working with a 3rd party grid (telerik kendo) that has paging/sorting/filtering built in. It will send the requests in a certain way when making the GET call and I'm trying to determine if there is a way to translate these requests to AutoQuery friendly requests.
Query string params
Sort Pattern:
sort[{0}][field] and sort[{0}][dir]
Filtering:
filter[filters][{0}][field]
filter[filters][{0}][operator]
filter[filters][{0}][value]
So this which is populated in the querystring:
filter[filters][0][field]
filter[filters][0][operator]
filter[filters][0][value]
would need to be translated to.
FieldName=1 // filter[filters][0][field]+filter[filters][0][operator]+filter[filters][0][value] in a nutshell (not exactly true)
Should I manipulate the querystring object in a plugin by removing the filters (or just adding the ones I need) ? Is there a better option here?
I'm not sure there is a clean way to do this on the kendo side either.
I will explain the two routes I'm going down, I hope to see a better answer.
First, I tried to modify the querystring in a request filter, but could not. I ended up having to run the autoqueries manually by getting the params and modifying them before calling AutoQuery.Execute. Something like this:
var requestparams = Request.ToAutoQueryParams();
var q = AutoQueryDb.CreateQuery(requestobject, requestparams);
AutoQueryDb.Execute(requestobject, q);
I wish there was a more global way to do this. The extension method just loops over all the querystring params and adds the ones that I need.
After doing the above work, I wasn't very happy with the result so I investigated doing it differently and ended up with the following:
Register the Kendo grid filter operations to their equivalent Service Stack auto query ones:
var aq = new AutoQueryFeature { MaxLimit = 100, EnableAutoQueryViewer=true };
aq.ImplicitConventions.Add("%neq", aq.ImplicitConventions["%NotEqualTo"]);
aq.ImplicitConventions.Add("%eq", "{Field} = {Value}");
Next, on the grid's read operation, we need to reformat the the querystring:
read: {
url: "/api/stuff?format=json&isGrid=true",
data: function (options) {
if (options.sort && options.sort.length > 0) {
options.OrderBy = (options.sort[0].dir == "desc" ? "-" : "") + options.sort[0].field;
}
if (options.filter && options.filter.filters.length > 0) {
for (var i = 0; i < options.filter.filters.length; i++) {
var f = options.filter.filters[i];
console.log(f);
options[f.field + f.operator] = f.value;
}
}
}
Now, the grid will send the operations in a Autoquery friendly manner.
I created an AutoQueryDataSource ts class that you may or may not find useful.
It's usage is along the lines of:
this.gridDataSource = AutoQueryKendoDataSource.getDefaultInstance<dtos.QueryDbSubclass, dtos.ListDefinition>('/api/autoQueryRoute', { orderByDesc: 'createdOn' });
export default class AutoQueryKendoDataSource<queryT extends dtos.QueryDb_1<T>, T> extends kendo.data.DataSource {
private constructor(options: kendo.data.DataSourceOptions = {}, public route?: string, public request?: queryT) {
super(options)
}
defer: ng.IDeferred<any>;
static exportToExcel(columns: kendo.ui.GridColumn[], dataSource: kendo.data.DataSource, filename: string) {
let rows = [{ cells: columns.map(d => { return { value: d.field }; }) }];
dataSource.fetch(function () {
var data = this.data();
for (var i = 0; i < data.length; i++) {
//push single row for every record
rows.push({
cells: _.map(columns, d => { return { value: data[i][d.field] } })
})
}
var workbook = new kendo.ooxml.Workbook({
sheets: [
{
columns: _.map(columns, d => { return { autoWidth: true } }),
// Title of the sheet
title: filename,
// Rows of the sheet
rows: rows
}
]
});
//save the file as Excel file with extension xlsx
kendo.saveAs({ dataURI: workbook.toDataURL(), fileName: filename });
})
}
static getDefaultInstance<queryT extends dtos.QueryDb_1<T>, T>(route: string, request: queryT, $q?: ng.IQService, model?: any) {
let sortInfo: {
orderBy?: string,
orderByDesc?: string,
skip?: number
} = {
};
let opts = {
transport: {
read: {
url: route,
dataType: 'json',
data: request
},
parameterMap: (data, type) => {
if (type == 'read') {
if (data.sort) {
data.sort.forEach((s: any) => {
if (s.field.indexOf('.') > -1) {
var arr = _.split(s.field, '.')
s.field = arr[arr.length - 1];
}
})
}//for autoquery to work, need only field names not entity names.
sortInfo = {
orderByDesc: _.join(_.map(_.filter(data.sort, (s: any) => s.dir == 'desc'), 'field'), ','),
orderBy: _.join(_.map(_.filter(data.sort, (s: any) => s.dir == 'asc'), 'field'), ','),
skip: 0
}
if (data.page)
sortInfo.skip = (data.page - 1) * data.pageSize,
_.extend(data, request);
//override sorting if done via grid
if (sortInfo.orderByDesc) {
(<any>data).orderByDesc = sortInfo.orderByDesc;
(<any>data).orderBy = null;
}
if (sortInfo.orderBy) {
(<any>data).orderBy = sortInfo.orderBy;
(<any>data).orderByDesc = null;
}
(<any>data).skip = sortInfo.skip;
return data;
}
return data;
},
},
requestStart: (e: kendo.data.DataSourceRequestStartEvent) => {
let ds = <AutoQueryKendoDataSource<queryT, T>>e.sender;
if ($q)
ds.defer = $q.defer();
},
requestEnd: (e: kendo.data.DataSourceRequestEndEvent) => {
new DatesToStringsService().convert(e.response);
let ds = <AutoQueryKendoDataSource<queryT, T>>e.sender;
if (ds.defer)
ds.defer.resolve();
},
schema: {
data: (response: dtos.QueryResponse<T>) => {
return response.results;
},
type: 'json',
total: 'total',
model: model
},
pageSize: request.take || 40,
page: 1,
serverPaging: true,
serverSorting: true
}
let ds = new AutoQueryKendoDataSource<queryT, T>(opts, route, request);
return ds;
}
}

How to query in mongodb programmatically?

I wannt to create code like this:
var result = Attributes.find({
attribute_name : {
$exist : true,
$in : [1]
}
});
but programmatically, so i ceate code like this:
var genQuery = '{ "' + by + '" : { "$exists" : true, "$in" : [' + data + ']} }';
var result = Attributes.find(genQuery);
but I get error maximum call stack
because result of JSON.parse(genQuery)
{ _id: { '$exists': true, '$in': [ 1 ] } }
How to query in mongodb programmatically?
Your genQuery variable you declare is a String, but you cannot pass strings as selectors or modifiers in find() functions.
You should create an Object to make it works:
var genQuery = {};
//use this notation to declare a new object key depending on a variable
genQuery[by] = {
$exists: true,
$in: [1]
};
var result = Attributes.find(genQuery);

Read csv to object of object for d3 [datamaps]

I'm using datamaps and would like to be able to read the data from a csv file.
The data format that datamaps is expecting is the following:
var loadeddata = {
"JPN":{Rate:17.5,fillKey:"firstCat"},
"DNK":{Rate:16.6,fillKey:"secondCat"}
};
I would like to read a csv file of the following structure and transform it into the format that datamaps is expecting:
ISO, Rate, fillKey
JPN, 17.5, firstCat
DNK, 16.6, secondCat
My 'best attempt' was using the following code:
var csvloadeddata;
d3.csv("simpledata.csv", function (error, csv) {
if (error) return console.log("there was an error loading the csv: " + error);
console.log("there are " + csv.length + " elements in my csv set");
var nestFunction = d3.nest().key(function(d){return d.ISO;});
csvloadeddata = nestFunction.entries(
csv.map(function(d){
d.Rate = +d.Rate;
d.fillKey = d.fillKey;
return d;
})
);
console.log("there are " + csvloadeddata.length + " elements in my data");
});
But this code generates a variable 'csvloadeddata' that looks like this:
var csvloadeddata = [
{"key": "JPN", "values": { 0: {Rate:17.5, fillKey:"firstCat"}} },
{"key": "DNK", values : { 1: {Rate:16.6,fillKey:"secondCat"}} }
];
What am I doing wrong?
Found the answer myself. If somebody is interested – this is what I ended up using:
<script>
d3.csv("simpledata.csv", function(error, csvdata1) {
globalcsvdata1 = csvdata1;
for (var i=0;i<csvdata1.length;i++)
{
globalcsvdata1[ globalcsvdata1[i].ISO] = globalcsvdata1[i] ;
//console.log(globalcsvdata1[i]);
delete globalcsvdata1[i].ISO;
delete globalcsvdata1[i] ;
}
myMap.updateChoropleth(globalcsvdata1);
}
);
var myMap = new Datamap({
element: document.getElementById('map'),
scope: 'world',
geographyConfig: {
popupOnHover: true,
highlightOnHover: false
},
fills: {
'AA': '#1f77b4',
'BB': '#9467bd',
defaultFill: 'grey'
}
});
</script>
</body>
The csv has the following structure:
ISO,fillKey
RUS,AA
USA,BB
Here is a working example: http://www.explainingprogress.com/wp-content/uploads/datamaps/uploaded_gdpPerCapita2011_PWTrgdpe/gdpPerCapita2011_PWTrgdpe.html