How to format the JSON object key/value pair - json

I am new to nodejs, right now I am able to fetch the data from the database and display as REST API which is of key/value pair. My output looks like as shown below
[{"id":"793","actionname":"test_bsc_interface","actionid":"100"}].
But I need to format as
{ "header" : [id,actionname,actionid],
"values" : [793 ,test_bsc_interface,100] ],}.
I tried with JSON.stringfy and checked few website but it's not working.
Could any one please help me through which link I should go through or approach.

The easy way to do it is to use underscore or lodash module to format it:
var _ = require('lodash');
var data = [{"id":"793","actionname":"test_bsc_interface","actionid":"100"}];
var result = _.map(data, function(o) {
return {headers: _.keys(o), values : _.values(o)}
});
console.dir(result);
Output is:
[
{
headers: [ 'id', 'actionname', 'actionid' ],
values: [ '793', 'test_bsc_interface', '100' ]
}
]
To get the result you want, just do result[0]
Note that I use _.map() instead of data[0] because this will work for the array (your array result from the query) that has more than 1 item.
Revised answer according to your comment (1 header line and all value lines in an array):
var _ = require('lodash');
var data = [
{ id: '714', actionname: 'test_bsc_interface', actionid: '100' },
{ id: '715', actionname: 'list_all_available_interfaces', actionid: '103' },
{ id: '716', actionname: 'check_tt', actionid: '101' }
];
var result;
if (_.size(data) > 0) {
result = {
headers: _.keys(data[0]),
values: _.map(data, function(o) {
return _.values(o);
})
};
}
console.dir(result);
and the output is:
{
headers: [ 'id', 'actionname', 'actionid' ],
values: [
[ '714', 'test_bsc_interface', '100' ],
[ '715', 'list_all_available_interfaces', '103' ],
[ '716', 'check_tt', '101' ]
]
}

Related

Adding values to 2D array with forEach

I am trying to add values to a 2D array in Google Apps Script. The following code runs, but is not the desired output for the array.
function fruitList() {
var fruitArray = [['apple'], ['banana'], ['cherry']];
var newArray = [];
fruitArray.forEach(function(value) {
newArray.push([value, "name"]);
});
}
My code yields the following output:
[ [ [ 'apple' ], 'name' ], [ [ 'banana' ], 'name' ], [ [ 'cherry' ], 'name' ] ]
My desired output is:
[ [ 'apple', 'name' ], [ 'banana', 'name' ], [ 'cherry', 'name' ] ]
value is a array. Not a string/primitive value. You can use destructuring assignment to get the actual value:
fruitArray.forEach(function([/*destructure 1D array*/value]) {
newArray.push([value, "name"]);
});
/*<ignore>*/console.config({maximize:true,timeStamps:false,autoScroll:false});/*</ignore>*/
function fruitList() {
var fruitArray = [['apple'], ['banana'], ['cherry']];
var newArray = [];
fruitArray.forEach(function([value]) {
newArray.push([value, "name"]);
});
console.info(newArray)
}
fruitList()
<!-- https://meta.stackoverflow.com/a/375985/ --> <script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
Add a value:
function fruitList() {
var fruitArray = [['apple'], ['banana'], ['cherry']];
var newArray = [];
fruitArray.forEach(function(value) {
newArray.push([value[0], "name"]);
});
Logger.log(JSON.stringify(newArray))
}
Execution log
3:27:33 PM Notice Execution started
3:27:34 PM Info [["apple","name"],["banana","name"],["cherry","name"]]
3:27:34 PM Notice Execution completed

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);

Try to get key values recursively from JSON in Angular 5

I want to retrieve all the key values from a JSON file. For example in :
{
"total_count": 6,
"incomplete_results": false,
"items": [
{
"url": "https://api.github.com/repos/Samhot/GenIHM/issues/6",
"id": 293237635,
"number": 6,
"title": "Rechercher des documents",
"user": {
"login": "Samhot",
"id": 7148311
]
}
I would like to get :
["total_count", "incomplete_results", "items", "url", "url", "number", "title", "user", "login", "id"]
I have a function which return the content of my JSON in an observable :
getConfig(): Observable<any> {
return this.http.get<any>(this.myURL);
}
After that the data are reformated with .map to get only the keys with the Object.keys() function :
merge()
.pipe(
startWith({}),
switchMap(() => {
return this.getConfig();
}),
map(data => {
return Object.keys(data.items[0]);
}
)
)
.subscribe(data => {
this.dispo = data;
});
My problem is that i get only the keys that are in the level of the JSON I told
(data.items[0]) and not the ascendants or the descendants.
Of course I can create multiple requests but it asks to know in advance the structure of the JSON, what I want is to make it generic ...
How can I do to have an array with with all of my keys regardless of the structure of the JSON ?
Thanks in advance !
You would need to do a recursive function like:
function getDeepKeys(obj) {
const keys = Object.keys(obj);
const childKeys = keys
.map(key => obj[key])
.map(
value =>
Array.isArray(value)
? getDeepKeys(value[0])
: typeof value === "object"
? getDeepKeys(value)
: []
)
.reduce((acc, keys) => [...acc, ...keys], []);
return [...keys, ...childKeys];
}
const obj = {
total_count: 6,
incomplete_results: false,
items: [
{
url: "https://api.github.com/repos/Samhot/GenIHM/issues/6",
id: 293237635,
number: 6,
title: "Rechercher des documents",
user: {
login: "Samhot",
id: 7148311
}
},
{
url: "https://api.github.com/repos/Samhot/GenIHM/issues/6",
id: 293237635,
number: 6,
title: "Rechercher des documents",
user: {
login: "Samhot",
id: 7148311
}
}
]
};
console.log(getDeepKeys(obj));
Which then you would use like map(getDeepKeys). Note that this function assumes all the items in your array have the same schema.

How to get sub document only in mongoose?

I'm trying to extract only sub document from an array has the following schema :
const UserSchema = Schema({
name: {
type: String
},library:[{
story:{type: Schema.Types.ObjectId,ref: 'Story'}
}],
});
i tried to use :
module.exports.getUserStories = function(userId, callback){
User.findOne({_id: userId },callback)
.select('library.story')
};
and it gives this result :
{
"_id": "5949615072e15d2b34fa8f9d",
"library": [
{
"story": "592ae46cf2a0ba2b208cb092"
},
{
"story": "592ae608df26d80790092fe9"
},
{
"story": "592ae46cf2a0ba2b208cb092"
}
]
}
but what i'm expecting to get is only this :
[
{
"story": "592ae46cf2a0ba2b208cb092"
},
{
"story": "592ae608df26d80790092fe9"
},
{
"story": "592ae46cf2a0ba2b208cb092"
}
]
I already tried to use double selection like :
module.exports.getUserStories = function(userId, callback){
User.findOne({_id: userId },callback)
.select('library.story')
.select('story')
};
But is gives the same result
Try this one :
module.exports.getUserStories = function(userId, callback){
User.find({_id: userId },{'library.story'}).then(function(user){
if(user){
callback(user.library);
}});
};
Docs here
This output is expected to return by "select" but simply you can prepare the returned data to be as you need as following:
User.findOne({_id: userId }).select('library').then(function(result){
if(result){
//If there is returned item
var stories = result.library;
//Continue ...
}
},function(error){
//Error handling
})

Getting json object data with react

I am attempting to pull data out of json like this, which is imported as "values"
{
"content": {
"person": [
{
"name": "Test"
"age" : "24:
}
]
}
}
I am using .map like below but getting the error .default.map is not a function I believe it is because i have objects not arrays, i've tried a bunch of stuff including object.keys but i'm getting errors all over the place, any direction would be appreciated.
import values from './sample.json'
const vals = values.map((myval, index) => {
const items = person.items.map((item, i) => {
return (
<div>{item.name}</div>
)
})
return (
<div>{items}</div>
)
})
I think your data and code have some errors. But after fixing those and also changing the name from 'person' to 'people' if that's what you are after, here's the code that does what you are trying to do:
var data = {
content: {
people: [
{
name: "Test",
age: 24,
},
{
name: "Foo",
age: 25,
},
],
},
};
var App = React.createClass({
render: function () {
var people = data.content.people.map(function (person) {
return <div>{person.name}</div>;
});
return <div>{people}</div>;
},
});
ReactDOM.render(<App />, document.getElementById("app"));
And here's the JSBin for that: https://jsbin.com/coyalec/2/edit?html,js,output
Update: I'm updating the answer with more detailed example. It now deals with data more generically, like it doesn't assume what are the entries of 'contents' and such, but it knows that each type like 'people' or 'pets' are an array.
var data = {
content: {
people: [
{
name: "Test",
age: 24,
},
{
name: "Foo",
age: 25,
},
],
pets: [
{
name: "Sweety",
age: 3,
},
{
name: "Kitty",
age: 5,
},
],
},
};
var App = React.createClass({
render: function () {
// Get the keys in data.content. This will return ['people', 'pets']
var contentKeys = Object.keys(data.content);
// Now start iterating through these keys and use those keys to
// retrieve the underlying arrays and then extract the name field
var allNames = contentKeys.map((t) =>
data.content[t].map((e) => <div>{e.name}</div>)
);
return <div>{allNames}</div>;
},
});
ReactDOM.render(<App />, document.getElementById("app"));
And here's the latest JSBin: https://jsbin.com/coyalec/4/edit?html,js,output