Iterate through JSON Object to get all objects with property - json

I am trying to iterate through the following JSON document in order to get the names of skating rinks:
I can get one name; however, what I am trying to do is loop through all of the entries (there are 253) and return a list of all the names.
Here is my React component:
class Patinoire extends Component {
constructor(props) {
super(props);
this.state = { patinoires: [] };
}
componentDidMount() {
var url = 'http://localhost:3000/patinoires'
fetch(url).then(function(response) {
if (response.status >= 400) {
throw new Error("Bad response from server");
}
return response.json();
})
.then(data => this.setState ({ patinoires: data.patinoires }));
}
render() {
var patinoires = this.state.patinoires;
var pjs2 = Object.values(patinoires);
var pjs3 = pjs2.map(x => x["2"].nom);
return <div>{pjs3}</div>
}
}
Right now, when using {pjs3}, I get the name of 3rd skating rink of the JSON document. How can I loop through all the entries and return the name property of all the entries?
EDIT: here is a sample of the data
{
"patinoires": {
"patinoire": [
{
"nom": [
"Aire de patinage libre, De la Savane (PPL)"
],
"arrondissement": [
{
"nom_arr": [
"Côte-des-Neiges - Notre-Dame-de-Grâce"
],
"cle": [
"cdn"
],
"date_maj": [
"2018-01-12 09:08:25"
]
}
],
"ouvert": [
""
],
"deblaye": [
""
],
"arrose": [
""
],
"resurface": [
""
],
"condition": [
"Mauvaise"
]
},
{
"nom": [
"Aire de patinage libre, Georges-Saint-Pierre (PPL)"
],
"arrondissement": [
{
"nom_arr": [
"Côte-des-Neiges - Notre-Dame-de-Grâce"
],
"cle": [
"cdn"
],
"date_maj": [
"2018-01-12 09:08:25"
]
}
],
"ouvert": [
""
],
"deblaye": [
""
],
"arrose": [
""
],
"resurface": [
""
],
"condition": [
"Mauvaise"
]
}
]
}
}

You can use Array.prototype.reduce() to flatten the result data with combination of Array.prototype.map() or Array.prototype.forEach().
Here is a running example:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
patinoires: {
patinoire: [
{
nom: ["Aire de patinage libre, De la Savane (PPL)"],
arrondissement: [
{
nom_arr: ["Côte-des-Neiges - Notre-Dame-de-Grâce"],
cle: ["cdn"],
date_maj: ["2018-01-12 09:08:25"]
}
],
ouvert: [""],
deblaye: [""],
arrose: [""],
resurface: [""],
condition: ["Mauvaise"]
},
{
nom: ["Aire de patinage libre, Georges-Saint-Pierre (PPL)"],
arrondissement: [
{
nom_arr: ["Côte-des-Neiges - Notre-Dame-de-Grâce"],
cle: ["cdn"],
date_maj: ["2018-01-12 09:08:25"]
}
],
ouvert: [""],
deblaye: [""],
arrose: [""],
resurface: [""],
condition: ["Mauvaise"]
}
]
}
};
}
renderData = () => {
const { patinoires } = this.state;
const markup = patinoires.patinoire.reduce((result, current) => {
current.nom.map(n => {
return result.push(<div>{n}</div>);
});
return result;
}, []);
return markup;
}
render() {
return <div>{this.renderData()}</div>;
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Try this:
var pjs2 = Object.values(patinoires);
var names = pjs2.reduce((accumulator, elem) => {
if (elem.patinoire) {
elem.patinoire.forEach(part => {
if(part.nom) {
part.nom.forEach((name) => accumulator.push(name));
}
});
}
return accumulator;
}, []);

Related

JSON only reading first element of array

I am working on a discord bot using Typescript, and I am having a problem reading from the config.JSON file.
This is the read vars function:
fs.readFile('config.json', 'utf8', function readFileCallback(err, data){
if (err){
console.log(err);
} else {
config = JSON.parse(data);
console.log(config);
const store = config.configstore[0];
roster = config.roster[0];
}});
and this is the config.json file:
{
"configstore": [
{"prefix": "!!"},
{"wallTime": 5},
{"bufferTime": 15},
{"wall": "false"},
{"buffer": "false"},
{"lastWallTime": "-1"},
{"lastBufferTime": "-1"},
{"wallCheckRole": "Role"},
{"bubfferCheckRole": "Role"}
],
"roster": [
{"discID":"discordID","ign":"IGN"}
]
}
When I print out the raw 'config' variable it prints this:
{
configstore: [
{ prefix: '!!' },
{ wallTime: 5 },
{ bufferTime: 15 },
{ wall: 'false' },
{ buffer: 'false' },
{ lastWallTime: '-1' },
{ lastBufferTime: '-1' },
{ wallCheckRole: 'Role' },
{ bubfferCheckRole: 'Role' }
],
roster: [ { discID: 'DiscordID', ign: 'IGN' } ]
}
But when I print the store variable it prints this:
{ prefix: '!!' }
The roster is normal as well.
The roles and ids are strings, but I changed it since I don't want them leaked.
These are some examples of what you are probably trying to achieve:
let config1 = {
"configstore": [
{"prefix": "!!"},
{"wallTime": 5},
{"bufferTime": 15},
{"wall": "false"},
{"buffer": "false"},
{"lastWallTime": "-1"},
{"lastBufferTime": "-1"},
{"wallCheckRole": "Role"},
{"bubfferCheckRole": "Role"}
],
"roster": [
{"discID":"discordID","ign":"IGN"}
]
}
let config2 = {
"configstore": [
{
"prefix": "!!",
"wallTime": 5,
"bufferTime": 15,
"wall": "false",
"buffer": "false",
"lastWallTime": "-1",
"lastBufferTime": "-1",
"wallCheckRole": "Role",
"bubfferCheckRole": "Role"
}
],
"roster": [
{"discID":"discordID","ign":"IGN"}
]
}
//prints {"prefix":"!!"}
console.log("configstore1:", JSON.stringify(config1.configstore[0]));
//prints {"discID":"discordID","ign":"IGN"}
console.log("roster1:", JSON.stringify(config1.roster[0]));
//prints {"prefix":"!!","wallTime":5,"bufferTime":15,"wall":"false","buffer":"false","lastWallTime":"-1","lastBufferTime":"-1","wallCheckRole":"Role","bubfferCheckRole":"Role"}
console.log("configstore2:", JSON.stringify(config2.configstore[0]));
//prints {"discID":"discordID","ign":"IGN"}
console.log("roster2:", JSON.stringify(config2.roster[0]));

How to export the api call results to a csv with the values of single response in one row?

My api response looks like below
[
{
"What time is it?": [
"option_2"
]
},
{
"When will we go home?": [
"option_1"
]
},
{
"When is your birthday?": [
"2050"
]
},
{
"How much do you sleep?": [
"Ajajajsjiskskskskdkdj"
]
}
],
[
{
"What time is it?": [
"option_2"
]
},
{
"When will we go home?": [
"option_1"
]
},
{
"When is your birthday?": [
"10181"
]
},
{
"How much do you sleep?": [
"Ajskossooskdncpqpqpwkdkdkskkskskksksksksks"
]
}
]
Now in react, I want to export the results to a csv. I can do it by export-to-csv but the formatting is the issue here. I want the values of each question of a single response in one row under their labels(questions). So if I have two response like above I want to have export it in two rows, not 8 as there are 8 total questions.
Here is how I want it to get exported.
I have tried so far like this but no luck.
this is my export data function
exp =()=>{
const raw = []
console.log(this.state.data[0].sbm_id)
axios.get(`/dashboard/${this.props.proj_id}/whole_sub/`)
.then(res=>{
// console.log('1')
// console.log(res.data[0][0])
// console.log('2')
for (let i =0;i<this.state.data.length;i++){
for(let j = 0;j<res.data[0].length;j++){
// let sub=[]
//res.data[i][j].ID = this.state.data[i].sbm_id
raw.push(res.data[i][j])
}
}
}
)
let curr = this.state
curr.exp = raw
this.setState({exp:curr.exp})
}
Here is my export function
rawExport=()=>{
const csvExporter = new ExportToCsv(optionsExp);
csvExporter.generateCsv(this.state.exp);
}
First step is to flatten the initial nested array to get a homogeneously shaped array, then you keep on reducing it further.
const data = [
[
{
"What time is it?": [
"option_2"
]
},
{
"When will we go home?": [
"option_1"
]
},
{
"When is your birthday?": [
"2050"
]
},
{
"How much do you sleep?": [
"Ajajajsjiskskskskdkdj"
]
}
],
[
{
"What time is it?": [
"option_2"
]
},
{
"When will we go home?": [
"option_1"
]
},
{
"When is your birthday?": [
"10181"
]
},
{
"How much do you sleep?": [
"Ajskossooskdncpqpqpwkdkdkskkskskksksksksks"
]
}
]
];
const flattenArray = (arr) => [].concat.apply([], arr);
// Flatten the initial array
const flattenedArray = flattenArray(data);
// Keep on reducing the flattened array into an object
var res = flattenedArray.reduce((acc, curr) => {
const [key, val] = flattenArray(Object.entries(curr));
if (!acc[key]) {
acc[key] = [].concat(val);
} else {
val.forEach(x => {
if (!acc[key].includes(x)) {
acc[key].push(x);
}
});
}
return acc;
}, {});
console.log(res);

How to use map on json response returned by a REST API with ReactJs

I've a json. The only thing I want is title from the json.
{
"projects": [
{
"id": 1,
"title": "Bike Servicing System",
"language": "JavaFX",
"requires": "JDK 8"
},
{
"id": 2,
"title": "Air Traffic Controller",
"language": "JavaFX",
"requires": "JDK 8"
},
{
"id": 3,
"title": "Program Counter",
"language": "JavaFX",
"requires": "JDK 8"
}
],
"profile": {
"name": "typicode"
}
}
I am using fetch and componentDidMount. I want to do it musing map method to iterate through. Though I don't need <ul> and <li> tags really. I will remove them later. My React code is
import React, { Component } from "react";
class ProjectStack extends Component {
constructor(props) {
super(props);
this.state = {
items: [],
isLoaded: false
};
}
componentDidMount() {
fetch("http://my-json-server.typicode.com/tmtanzeel/json-server/projects/")
.then(res => res.json())
.then(json => {
this.setState({
isLoaded: true,
items: json.projects
});
});
}
render() {
var { isLoaded, items } = this.state;
var i=0;
if (!isLoaded) return <div>Loading...</div>;
return (
<div>
<ul>
{
items.map(item => (
<li key={item[i++].id}>
Projects: {item[i++].title}
</li>
))
}
</ul>
</div>
);
}
}
export default ProjectStack;
Apparently, there is something that I don't know because I am getting this error.
PS: This question is different from mine
The JSON of the URL you are fetching is this:
[
{
"id": 1,
"title": "Bike Servicing System",
"language": "JavaFX",
"requires": "JDK 8"
},
{
"id": 2,
"title": "Air Traffic Controller",
"language": "JavaFX",
"requires": "JDK 8"
},
{
"id": 3,
"title": "Program Counter",
"language": "JavaFX",
"requires": "JDK 8"
},
{
"id": 4,
"title": "Dove Tail",
"language": "JavaFX",
"requires": "JDK 8"
}
]
So for correctly set the data in the state you need to:
componentDidMount() {
fetch("http://my-json-server.typicode.com/tmtanzeel/json-server/projects/")
.then(res => res.json())
.then(json => {
this.setState({
isLoaded: true,
items: json
});
});
}
Besides correcting the error they have already told you related the map loop.
I found 2 mistakes from your code.
The first one is you didn't check the response data.
fetch("http://my-json-server.typicode.com/tmtanzeel/json-server/projects/")
.then(res => res.json())
.then(json => {
console.log(json); // it is an Array not object.
this.setState({
isLoaded: true,
items: json
});
});
And the second is you didn't use the map() properly.
/*{
items.map(item => (
<li key={item[i++].id}>
Projects: {item[i++].title}
</li>
))
}*/
// items has objects, so you should use map() like this.
{
items.map(item => (
<li key={item.id}>
Projects: {item.title}
</li>
))
}
The below code is one way to achieve what you want.
class ProjectStack extends React.Component {
constructor(props) {
super(props);
this.state = {
items: [],
isLoaded: false
};
}
componentDidMount() {
fetch("http://my-json-server.typicode.com/tmtanzeel/json-server/projects/")
.then(res => res.json())
.then(json => {
console.log(json);
this.setState({
isLoaded: true,
items: json
});
});
}
render() {
const {
isLoaded,
items
} = this.state;
console.log(items);
if (!isLoaded) return ( < div > Loading... < /div>);
return ( <
div >
<
ul > {
items.map(item => ( <
li key = {
item.id
} > Projects: {
item.title
} < /li>
))
} <
/ul> <
/div>
);
}
}
ReactDOM.render( <
ProjectStack / > , document.getElementById('root')
)
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div id="root"></div>

In a JSON file I need to access to an attribute name with ':' in it

I'm a react-native noob.
I need to read a link inside a JSON field called 'wp:featuredmedia.href'.
obviusly i can't put the ':' char in the code.
I've tried in this way... but I've no success :(
componentDidMount(){
const { navigation } = this.props;
const id = navigation.getParam('id', );
//const percorso = 'responseJson.wp:featuredmedia.rendered';
return fetch('https://www.seisnet.it/wp-json/wp/v2/posts/'+id)
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
title: String(responseJson.title.rendered),
photos: String(responseJson.wp:featuredmedia),
}, function(){});
})
.catch((error) =>{
console.error(error);
});
}
EDIT 1
this is a section of the json file:
// 20190726085445
// https://www.seisnet.it/wp-json/wp/v2/posts/1967
"_links": {
"self": [
{
"href": "https://www.seisnet.it/wp-json/wp/v2/posts/1967"
}
],
"collection": [
{
"href": "https://www.seisnet.it/wp-json/wp/v2/posts"
}
],
"about": [
{
"href": "https://www.seisnet.it/wp-json/wp/v2/types/post"
}
],
"wp:featuredmedia": [
{
"embeddable": true,
"href": "https://www.seisnet.it/wp-json/wp/v2/media/1971"
}
],
"wp:attachment": [
{
"href": "https://www.seisnet.it/wp-json/wp/v2/media?parent=1967"
}
],
}
}
the field i've to read contains a link to another json file.
i've tried: JSONResponse_embedded["wp:featuredmedia"] and JSONResponse["wp:featuredmedia"]. the first give me the error "undefined is not an object" while the second give me nothing in output
Instead of responseJson.wp:featuredmedia, try responseJson["wp:featuredmedia"]
JavaScript object: access variable property by name as string

Jest coverage in redux reducer - object destruction not covered

I have the following issue with Jest:
I have this reducer:
[REMOVE_FILTER]: (state: FiltersState, action: Action<string>): FiltersState => {
const { [action.payload!]: deleted, ...activeFilters } = state.activeFilters;
return { ...state, activeFilters, createFilterSelection: undefined, filterCreateOpen: false };
}
When I am trying to test it, it says that I do not have coverage for
...activeFilters } = state.activeFilters;
Here is my test:
test(REMOVE_FILTER, () => {
const action: IAction<string> = {
type: REMOVE_FILTER,
payload: "subprovider"
};
expect(
testReducer({ reducer, state, action })
).toEqual({
...state,
activeFilters: { name: null, branded: null },
createFilterSelection: undefined,
filterCreateOpen: false
});
});
Can someone suggest what I am doing wrong?
I am using:
Jest 23.6.0
Typescript 3.4.0
Redux 4.0.0
React-Redux: 6.0.0
Redux Actions: 2.6.1
Thank you!
P.S: Here is the Jest config:
{
"coverageThreshold": {
"global": {
"branches": 100,
"functions": 100,
"lines": 100,
"statements": 100
}
},
"globals": {
"window": true,
"document": true
},
"transform": {
".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "(/__test__/.*)\\.test\\.(ts|tsx)$",
"notify": true,
"collectCoverageFrom": [
"**/*.{ts,tsx}"
],
"coveragePathIgnorePatterns": [
"(/__e2e__/.*)",
"(/__specs__/.*)",
"(/__test__/.*)",
"(/interfaces/.*)",
"(index.ts)",
"(src/server/app.ts)",
"(src/server/config.ts)",
"(/mock/.*)",
"(data/mock.ts)",
"(automapperConfiguration.ts)",
"(src/app/store/store.ts)",
"(src/app/containers/brand-configuration/.*)"
],
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"json"
],
"setupTestFrameworkScriptFile": "<rootDir>/jestSetup.js",
"testURL": "http://localhost/"
}
The above TS code gets transpilled to:
[REMOVE_FILTER]: (state, action) => {
const _a = state.activeFilters, _b = action.payload, deleted = _a[_b], activeFilters = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
return Object.assign({}, state, { activeFilters, createFilterSelection: undefined, filterCreateOpen: false });
}