I'm getting data from a geojson file and I want to flatten an array within an array to be able to show this data within a material table.
I have the following code:
const geoListData: Array<any> = [];
const features = geoData.features; // feature array
const latIdx = 0;
const lonIdx = 1;
// iterate over each feature
features.forEach((feature: any) => {
const geoListArray: any = [];
// build up GeoListEntry
const geoListEntry: GeoListEntry = {
name: feature.properties.name,
category: feature.properties.category,
lat: feature.geometry.coordinates[latIdx],
lon: feature.geometry.coordinates[lonIdx],
prio: feature.properties.prio
};
geoListArray.push(geoListEntry);
// get values from geojson
feature.properties.values.forEach((element: any) => {
const valuesEntry: any = {
[element.name]: element.value
};
geoListArray.push(valuesEntry);
});
this.logger.debug(`geoListArray: ${JSON.stringify(geoListArray)}`);
geoListData.push(geoListArray);
});
return geoListData;
}));
My logger output looks like that:
[{"name":"90","category":"Arc 12 month","lat":7.613333333,"lon":47.555555,"prio":0},{"bearing":12345},{"intensity_mean":0},{"intensity_min":0},{"intensity_max":0}]
But I want something like that:
[{"name":"90","category":"Arc 12 month","lat":7.613333333,"lon":47.555555,"prio":0,"bearing":12345,"intensity_mean":0,"intensity_min":0,"intensity_max":0}]
I'm close, but I can't find the solution.
Do you have any idea?
Instead of pushing it to array, add property directly to the object
// iterate over each feature
features.forEach((feature: any) => {
const geoListArray: any = [];
// build up GeoListEntry
const geoListEntry: GeoListEntry = {
name: feature.properties.name,
category: feature.properties.category,
lat: feature.geometry.coordinates[latIdx],
lon: feature.geometry.coordinates[lonIdx],
prio: feature.properties.prio
};
// get values from geojson
feature.properties.values.forEach((element: any) => {
geoListEntry[element.name] = element.value
});
geoListArray.push(geoListEntry);
this.logger.debug(`geoListArray: ${JSON.stringify(geoListArray)}`);
geoListData.push(geoListArray);
});
Related
Learning JavaScript. I need to plot some data (I'm using Nivo).
I have data from my API in the format of:
[{"as_at_date":"2020-02-21","value":815202269.5,"num":139},{"as_at_date":"2020-02-25","value":809209302.32,"num":139},{"as_at_date":"2020-03-12","value":723686212.35,"num":139},{"as_at_date":"2020-03-13","value":734798809.24,"num":139},{"as_at_date":"2020-03-16","value":701366943.2,"num":139},{"as_at_date":"2020-03-17","value":710833514.89,"num":139},{"as_at_date":"2020-03-18","value":699154469.83,"num":139},{"as_at_date":"2020-03-19","value":694649684.34,"num":139},{"as_at_date":"2020-03-20","value":685400033.9,"num":139}]
To plot a line chart with Nivo I need to alter the above array into:
[{"id": 'XXXXX",
"data": [{"x":"2020-02-21","y":815202269.5},{"x":"2020-02-25","y":809209302.32},{"x":"2020-03-12","y":723686212.35},{"x":"2020-03-13","y":734798809.24},{"x":"2020-03-16","y":701366943.2},{"x":"2020-03-17","y":710833514.89},{"x":"2020-03-18","y":699154469.83},{"x":"2020-03-19","y":694649684.34},{"x":"2020-03-20","y":685400033.9}]
Ignore "num" property.
nest the data and create an "id"
Change as_at_date to "x", value to "y"
Last attempt was trying to use .map like .map(item => [{"x": item['as_at_date']}, {"y": item['value']}]) but wasn't quite right.
Appreciate any help, thanks!
I would use .reduce() to create the nested data first. Then adding id and data properties to the final object.
Try the following:
const data = [{"as_at_date":"2020-02-21","value":815202269.5,"num":139},{"as_at_date":"2020-02-25","value":809209302.32,"num":139},{"as_at_date":"2020-03-12","value":723686212.35,"num":139},{"as_at_date":"2020-03-13","value":734798809.24,"num":139},{"as_at_date":"2020-03-16","value":701366943.2,"num":139},{"as_at_date":"2020-03-17","value":710833514.89,"num":139},{"as_at_date":"2020-03-18","value":699154469.83,"num":139},{"as_at_date":"2020-03-19","value":694649684.34,"num":139},{"as_at_date":"2020-03-20","value":685400033.9,"num":139}];
const nested = data.reduce((a, c) => a.concat({x: c['as_at_date'], y: c['value']}), []);
const result = {
id: 'XXXXX',
data: nested
};
console.log(result);
I hope this helps!
map is certainly the way to go.
Here's my approach:
const data = [{"as_at_date":"2020-02-21","value":815202269.5,"num":139},{"as_at_date":"2020-02-25","value":809209302.32,"num":139},{"as_at_date":"2020-03-12","value":723686212.35,"num":139},{"as_at_date":"2020-03-13","value":734798809.24,"num":139},{"as_at_date":"2020-03-16","value":701366943.2,"num":139},{"as_at_date":"2020-03-17","value":710833514.89,"num":139},{"as_at_date":"2020-03-18","value":699154469.83,"num":139},{"as_at_date":"2020-03-19","value":694649684.34,"num":139},{"as_at_date":"2020-03-20","value":685400033.9,"num":139}];
function reformattedData(arr) {
// Destructure only the required properties
return arr.map(({ as_at_date, value }) => {
// And just return those values in a new object
// using the new property names
return { x: as_at_date, y: value };
});
}
const out = { id: 'xxx', data: reformattedData(data) };
console.log(out);
Your attempt was almost correct, just omit the surrounding []:
const input = [{"as_at_date":"2020-02-21","value":815202269.5,"num":139},{"as_at_date":"2020-02-25","value":809209302.32,"num":139},{"as_at_date":"2020-03-12","value":723686212.35,"num":139},{"as_at_date":"2020-03-13","value":734798809.24,"num":139},{"as_at_date":"2020-03-16","value":701366943.2,"num":139},{"as_at_date":"2020-03-17","value":710833514.89,"num":139},{"as_at_date":"2020-03-18","value":699154469.83,"num":139},{"as_at_date":"2020-03-19","value":694649684.34,"num":139},{"as_at_date":"2020-03-20","value":685400033.9,"num":139}];
const outputData = input.map(item => ({ x: item.as_at_date, y: item.value }));
console.log(outputData);
const result = {
id: 'XXXX', // create your id here,
data: outputData,
};
console.log(result);
You can try this one
const array = [{"as_at_date":"2020-02-21","value":815202269.5,"num":139},{"as_at_date":"2020-02-25","value":809209302.32,"num":139},{"as_at_date":"2020-03-12","value":723686212.35,"num":139},{"as_at_date":"2020-03-13","value":734798809.24,"num":139},{"as_at_date":"2020-03-16","value":701366943.2,"num":139},{"as_at_date":"2020-03-17","value":710833514.89,"num":139},{"as_at_date":"2020-03-18","value":699154469.83,"num":139},{"as_at_date":"2020-03-19","value":694649684.34,"num":139},{"as_at_date":"2020-03-20","value":685400033.9,"num":139}];
const formatted_array = input.map((item) => {
return {x: item.as_at_date, y: item.value}});
const final_data = {
id: 'XXXX',
data: formatted_array ,
};
console.log(final_data);
I'm getting a list of objects as a response like this
As you can see the objects are not in an array. I want to push these objects into an array. I tried the following way
this.setState({
countrydata: this.state.countrydata.push(datasnapshot.val()),
})
But it didn't work. What's the correct approach to push these objects into an array?
PS:
componentDidMount() {
const countryCode = this.props.match.params.countryCode;
var countryName = getName(countryCode);
var firebaseHeadingref = firebase.database().ref(countryCode);
firebaseHeadingref.once('value').then(datasnapshot => {
this.setState({
countrydata: datasnapshot.val(),
countryName: countryName,
loading: false
})
});
}
I think that the "countrydata" in a dict not an array.
Try to initialize the it as an empty array.
Array.prototype.push returns the new length of the array after the push, so you are essentially setting the state to a number.
You are not allowed to mutate the array with React state, you need to create a new array containing your new elements:
// When updating state based on current state, use the function form of setState.
this.setState(state => {
countrydata: [...state.countrydata, datasnapshot.val()],
})
This is assuming countryData is indeed an array, which from your screenshot, it appears to not (it seems to be an object), so you may be set something wrong somewhere along the way (or datasnapshot.val()) doesn't contain what you think it contains.
You could do this:
const keys = Object.keys(countryData); // array of the keys ["place_1", ...]
const array = Array(keys.length); // Prepares the output array of the right size
for (let i=0; i<keys.length; i++) {
const country = countryData[keys[i]]; // get the next country object
country.key = keys[i]; // add the key into the object if you need it
array[i] = country; // store the value into the array at index 'i'
}
// array now is [ {key: "place_1", description: "Sigiriya Rock Fortress"}, ...]
this.setState({countryDataArray: array});
You could try something like this. Array.prototype.push().
I have not tested below code.
componentDidMount=async() =>{
const countryCode = this.props.match.params.countryCode;
var countryName = getName(countryCode);
var firebaseHeadingref = firebase.database().ref(countryCode);
const datasnapshot = await firebaseHeadingref.once('value');
this.setState(prevState=>{
...prevState,
countryName,
countrydata: [...prevState.countrydata, datasnapshot.val()],
loading: false,
},()=>console.log("done!"))
}
You need to convert the response data from firebase to an array like this:
componentDidMount() {
const countryCode = this.props.match.params.countryCode;
var countryName = getName(countryCode);
var firebaseHeadingref = firebase.database().ref(countryCode);
firebaseHeadingref.once('value').then(datasnapshot => {
const countryData = datasnapshot.val();
const countryDataArray = [];
for (const key in countryData) {
countryDataArray.push({ key, ...countryData[key]});
}
this.setState({
countrydata: countryDataArray,
countryName: countryName,
loading: false
})
});
}
Use for-in to loop through the object or use Object.keys().
const data = datasnapshot.val();
const countrydata = [];
for (let key in data) {
countrydata.push(data[key])
}
// using Object.keys()
Object.keys(data).forEach((key) => countrydata.push({ [key]: data[key]}))
this.setState({
countrydata
})
const data = {
place1: { name: 'One'},
place2: { name: 'Two'},
place3: { name: 'Three'},
};
const countrydata = [];
for (let key in data) {
countrydata.push({ [key]: data[key] });
}
console.log(countrydata);
I have an object Regions{} which stores multiple objects, following code block showing countryName : [regions,..,..]
Regions = { Afghanistan:["Badakhshan~BDS", "Badghis~BDG", "Baghlan~BGL"]
Albania:["Berat~01", "Dibër~09", "Durrës~02",]
}
Which giving me result like this:
Afghanistan: Array(n)
0: "Badakhshan~BDS"
1: "Badghis~BDG"
what I am trying to achive is :
Afghanistan: Array(n)
0:{value: "Badakhshan", lable: "BDS"}
1:{value: "Badghis", lable: "BDG"}
thanks in advance
PS: for the sake of some ruthless fellows following is the code what I have tried yet
let countries = CountryRegionData
let regions = {}
countries = countries.map(country => {
regions = {
...regions,
[country[0]]: country[2].split('|')
}
return {
value: country[1],
label: country[0]
}
})
console.log("countries",countries)
console.log("regions",regions)
let values = regions["Afghanistan"];
values = values.map(value =>{
return {
value: value,
lable: value
}
})
You can use split and map, this code is changing values in original object, if you want to build a new object you can use reduce instead of forEach
let Regions = {
Afghanistan: ["Badakhshan~BDS", "Badghis~BDG", "Baghlan~BGL"],
Albania: ["Berat~01", "Dibër~09", "Durrës~02", ]
}
Object.entries(Regions).forEach(([key,value])=>{
Regions[key] = value.map(data=>{
let [value,label] = data.split('~')
return {value,label}
})
})
console.log(Regions)
Do something like:
Regions.map(region => region.map(txt => {
const [val, lbl] = txt.split("~");
return { value: val, lable: lbl};
}));
Messy but gets the work done. Using nested forEach loops
var Regions = {
Afghanistan: ["Badakhshan~BDS", "Badghis~BDG", "Baghlan~BGL"],
Albania: ["Berat~01", "Dibër~09", "Durrës~02", ]
}
var ar = [];
Object.keys(Regions).forEach(function(e) {
Regions[e].forEach(function(k) {
var arr = k.split('~');
ar.push({
value: arr[0],
label: arr[1]
})
})
Regions[e] = ar;
ar = [];
})
console.log(Regions)
Use the map function to iterate the object.
Regions = {
Afghanistan: ["Badakhshan~BDS", "Badghis~BDG", "Baghlan~BGL"],
Albania: ["Berat~01", "Dibër~09", "Durrës~02", ]
};
const finalObject = Object.keys(Regions).map(region => {
return {
[region]: Regions[region].map(country => {
const [value, lable] = country.split("~");
return {
value,
lable
};
})
};
});
console.log(finalObject);
I want to make filter by date with this object of array
const mapDateRange = () => {for (let elem in catchData) {
let x = {startDate:catchData[elem][0],finishDate:catchData[elem][1]};
return x;
}};
but its only catch one object of array
this is latest data has processing
const data = {
["01-08-2019", "08-08-2019"],
["08-08-2019", "15-08-2019"],
["15-08-2019", "22-08-2019"],
["22-08-2019", "29-08-2019"]
};
this is what i expected
const data = [
{
startDate:"01-08-2019", finisDate:"08-08-2019"
},
{
startDate:"08-08-2019", finisDate:"15-08-2019"
},
{
startDate:"15-08-2019", finisDate:"22-08-2019"
},
{
startDate:"22-08-2019", finisDate:"29-08-2019"
}
];
So there are a few problems in the code you wrote:
Your data started as an object ({}), but its built as an array, so I corrected that.
Your function mapDateRange uses catchData but it does not exist anywhere so I made the function except an argument, which will be the catchData.
Most important: You returned x which is only 1 item in the array of data. So I created an empty array and pushed x values to the array.
const data = [
["01-08-2019", "08-08-2019"],
["08-08-2019", "15-08-2019"],
["15-08-2019", "22-08-2019"],
["22-08-2019", "29-08-2019"]
];
const mapDateRange = (catchData) => {
let new_data = [];
for (let elem in catchData) {
let x = {
startDate: catchData[elem][0],
finishDate: catchData[elem][1]
};
new_data.push(x);
}
return new_data;
};
console.log(mapDateRange(data));
const data = [
["01-08-2019", "08-08-2019"],
["08-08-2019", "15-08-2019"],
["15-08-2019", "22-08-2019"],
["22-08-2019", "29-08-2019"]
];
const mapDataRange = (data) => {
const result = [];
data.forEach((item) => {
const x = { 'startDate': item[0], 'finishDate': item[1] };
result.push(x);
});
return result;
}
console.log(mapDatatRange(data));
In this way you will get your desire result by using map function
data = data.map((obj) => {
return {
startDate: obj[0],
finishDate: obj[1]
}
});
console.log(data)
try to do with .map and array destructuring with ES6 syntax
data.map(([ startDate, finishDate ]) => { startDate, finisDate })
In my post request I need to pass an array with an object inside it.
when I tried to add new properties inside an object its adding.
but when I tried to add when an object is present inside an array its not adding.
I have sportsvalues as array const sportsValues = [{ ...values }];
I am trying to build something like this, so that I can pass in the api
[
{
"playerName": 3,
"playerHeight": 1
}
]
can you tell me how to fix it.
providing my code snippet below.
export function sports(values) {
const sportsValues = [{ ...values }];
sportsValues.push(playerName:'3');
console.log("sportsValues--->", sportsValues);
// sportsValues.playerName = 3//'';
// sportsValues.playerHeight = 1//'';
console.log("after addition sportsValues--->", sportsValues);
console.log("after deletion sportsValues--->", sportsValues);
return dispatch => {
axios
.post(`${url}/sport`, sportsValues)
.then(() => {
return;
})
.catch(error => {
alert(`Error\n${error}`);
});
};
}
Since sportsValues is an array of objects, you can push new object into it. Check out code below.
const sportsValues = [];
sportsValues.push({
playerName:'3',
playerHeight: 1,
});
console.log(sportsValues);
I don't fully understand what you're trying to do, but here's some pointers:
If you're trying to update the object that's inside the array, you first have to select the object inside the array, then update it's attribute:
sportsValues[0].playerName = 3
although, I recommend building the object correctly first, then passing it to the array, it makes it a little easier to understand in my opinion:
const sportsValues = [];
const firstValue = { ...values };
firstValue.playerName = '3';
sportsValues.push(firstValue);
or
const firstValue = { ...values };
firstValue.playerName = '3';
const sportsValues = [firstValue];
or
const sportsValues = [{
...values,
playername: '3',
}];
if you're trying to add a new object to the array, you can do this:
const sportsValues = [{ ...values }];
sportsValues.push({ playerName: '3' });
etc...
Array.push adds a new item to the array, so in your code, you're going to have 2 items because you assign 1 item at the beginning and then push a new item:
const ar = [];
// []
ar.push('item');
// ['item']
ar.push({ text: 'item 2' });
// ['item', { text: 'item 2' }]
etc...
export function sports(values) {
const sportsValues = [{ ...values }];
sportsValues.push(playerName:'3');
let playerName='3'
sportsValues.playerName= playerName; // you can bind in this way
console.log("sportsValues--->", sportsValues);
return dispatch => {
axios
.post(`${url}/sport`, sportsValues)
.then(() => {
return;
})
.catch(error => {
alert(`Error\n${error}`);
});
};
}