How to get element from JSON array in array in array - arrays

I have a question about this JSON. How to get coordinates from here?
I try to use for(){} like code below but doesn't work.
item {
"type": "type1",
"features": [{
"type": "typeee1",
"geometry": {
"type": "Point",
"coordinates": [
-19.726330999999998,
41.360610000000001
]},
"properties": {
"id_strada": "1433",
"nome_strada": "test3",
} },
{
"type": "typeee2",
"geometry": {
"type": "Point",
"coordinates": [
19.726344999999998,
26.36063
] },
"properties": {
id_strada": "13",
"nome_strada": "test5",
} },
{
"type": "typeee3",
"geometry": {
"type": "Point",
"coordinates": [
19.726358999999999,
98.36065
] },
"properties": {
id_strada": "14",
"nome_strada": "test34",
} }, {
"type": "typeee5",
"geometry": {
"type": "Point",
"coordinates": [
19.726372999999999,
55.360669999999999
] },
"properties": {
id_strada": "14335",
"nome_strada": "test39",
} }],
"last_update": "15-08-2019 15:04:45"
}
function that call JSON is like below.
item: Item[];
this.ws.getitems().subscribe(
item => {
this.item = item;
console.log('this.item.length', this.item.length)
for (let i = 0; i < this.item.length; i++) {
}
}
);
this.item.length is undefined
My question is, how to get coordinates in here?
Can you ask me any idea please?
Thanks!

You don't have an array in an array in an array. You have an array in an object in an object in an array in an object.
interface Feature {
type: string;
geometry: {
type: string;
coordinates: [ number, number ];
};
properties: {
id_strada: string;
nome_strada: string;
};
}
interface Item {
type: string;
features: Feature[];
last_update: string;
}
const items$: Observable<Item> = this.ws.getItems();
const coordinates$: Observable<[number, number]> = items$.pipe(
switchMap((item: Item) => of(
...item.features.map((feature: Feature) => feature.geometry.coordinates)
)),
);
coordinates$.subscribe((coordinates: [number, number]) => console.log(coordinates));
It is really unclear exactly what your intention is here. Your Item object has multiple coordinates within it. Do you intend to link all of the coordinates, or just the first, or do you want to split them by feature? I've provided you a way to just have an unlinked stream of all coordinates you ever receive. You'll have to figure out what it is you want to do with that.

If you were already in item, coordinates are at item.geometry.coordinates
If your supplied json was x, you could get the first coordinates at x.features[0].geometry.coordinates.
You could find each set of coordinates with:
x.features.forEach(item => {
let coords = item.geometry.coordinates
// do something with coords
})

Related

How to create nested array in realm without key(React Native)

{
"a": [
[
{
"_id": "57e55b64016c3551c025abc1",
"title": "Main Campus"
},
{
"_id": "5810e2e27064497f74ad4874",
"title": "Ahm Campus"
},
{
"_id": "5d5d2633a1d0680620ac3cce",
"title": "Baroda"
},
{
"_id": "5d5d3af3a1d0680620ac3ef8",
"title": "India"
}
],
[
{
"_id": "57e55b64016c3551c025abc1",
"title": "Main Campus"
},
{
"_id": "5810e2e27064497f74ad4874",
"title": "Ahm Campus"
},
{
"_id": "5d5d2633a1d0680620ac3cce",
"title": "Baroda"
},
{
"_id": "5d5d3af3a1d0680620ac3ef8",
"title": "India"
}
]
]
}
How to create the schema in the realm(React native) for this type of JSON object. I tried all possible ways but did not found any specific solution. Basically, it is a nested array where the second array does not have any specific key(I tried with key it works fine but I want to do it without adding key).
You can use something like:
const ParentSchema = {
name: "parent",
properties: {
key: "string",
values: "Value[]"
}
};
const ValueSchema = {
name: "Value",
embedded: true,
properties: {
_id: "string",
title: "string"
}
};
You can insert objects like:
realm.write(() => {
realm.create("Parent", { key: "a", values: [
{ _id: "57e55b64016c3551c025abc1", title: "Main Campus" },
{ _id: "5810e2e27064497f74ad4874", title: "Ahm Campus" }
]
});
});
Documentation: https://docs.mongodb.com/realm/node/data-model
As of now there is no way to insert direct value in Realm database without key so for now we need to modify data and then we can store in following schema.
const ParentSchema = {
name: "parent",
properties: {
a: "level[]"
}
};
const level = {
name: 'level',
properties: {
level: 'sites[]'
}
}
const sites = {
name: 'sites',
properties: {
sites: 'site[]'
}
}
const site = {
name: 'site',
properties: {
title: 'string?',
_id: 'string?',
version: 'int?',
}
}
Data modification need to done like following.
var a = {
level: []
}
data.a.map((Site, index) => {
const sites = []
Site.map((s) => { sites.push(s)})
a.level.push({sites})
})

JSON schema for an unnamed array?

I need to create a JSON schema for data that comes as an array directly within the root object, unnamed. An MWE for this kind of JSON would be:
{
[
{
"veggieName": "potato",
"veggieLike": true
},
{
"veggieName": "broccoli",
"veggieLike": false
}
]
}
I have seen examples for schemas which validate such an array which is not nested in an object. I have also seen examples which work when the array is named, for example
{
vegetables : [
{
"veggieName": "potato",
"veggieLike": true
},
{
"veggieName": "broccoli",
"veggieLike": false
}
]
}
This second example can be validated by the schema
{
"$id": "https://example.com/arrays.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "A representation of a person, company, organization, or place",
"type": "object",
"properties": {
"vegetables": {
"type": "array",
"items": { "$ref": "#/definitions/veggie" }
}
},
"definitions": {
"veggie": {
"type": "object",
"required": [ "veggieName", "veggieLike" ],
"properties": {
"veggieName": {
"type": "string",
"description": "The name of the vegetable."
},
"veggieLike": {
"type": "boolean",
"description": "Do I like this vegetable?"
}
}
}
}
}
But the problem is, as soon as the name "vegetables" is removed, I was not able to find a way to define a valid schema. How do I properly represent my data structure in a schema?
(MWEs derived from http://json-schema.org/learn/miscellaneous-examples.html).
The schema you are looking for is the following:
{
"$id":"https://example.com/arrays.schema.json",
"$schema":"http://json-schema.org/draft-07/schema#",
"description":"A representation of a person, company, organization, or place",
"type":"array",
"items":{
"type":"object",
"required":[
"veggieName",
"veggieLike"
],
"properties":{
"veggieName":{
"type":"string",
"description":"The name of the vegetable."
},
"veggieLike":{
"type":"boolean",
"description":"Do I like this vegetable?"
}
}
}
}
You also need to modify your base array instance, your original one (the "unnamed" array) was not valid JSON:
[
{
"veggieName":"potato",
"veggieLike":true
},
{
"veggieName":"broccoli",
"veggieLike":false
}
]
Unlike XML, where you are allowed a single root node per document only, in JSON you can have either a type or an array as a root type.

Importing geojson to react-leaflet-draw

I am trying to import some GeoJSON to the FeatureGroup in _onFeatureGroupReady event handler, but it doesn't appear to be rendered into the map. The code is mostly based on the example from the library react-leaflet-draw here. Strangely, the edit menu becomes usable, indicating that the data is maybe there, but just not being rendered.
I'm not sure what's happening, as I'm a beginner to maps in general. The relevant code is in the else if(this.props.data) { block. The console.log() statements all show the data being there and in the correct format.
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
37.79,
-122.45
],
[
37.79,
-122.42999999999999
],
[
37.77,
-122.42999999999999
],
[
37.77,
-122.45
],
[
37.79,
-122.45
]
]
]
}
}
]
}
Here is the code where I'm trying to import this data into the FeatureGroup:
_onFeatureGroupReady = (ref) => {
console.log('_onFeatureGroupReady');
console.log(ref);
if(ref===null) {
return;//bug???
}
this._editableFG = ref;
// populate the leaflet FeatureGroup with the geoJson layers
if(this.state.data) {
console.log('importing service area from state');
let leafletGeoJSON = new L.GeoJSON(this.state.data);
let leafletFG = this._editableFG.leafletElement;
leafletGeoJSON.eachLayer( layer =>leafletFG.addLayer(layer));
}else if(this.props.data) {
console.log('importing service area from props');
this.setState({data:this.props.data},()=>{
console.log(this.state.data);
let leafletGeoJSON = new L.GeoJSON(this.state.data);
console.log(leafletGeoJSON);
let leafletFG = this._editableFG.leafletElement;
console.log(leafletFG);
leafletGeoJSON.eachLayer( layer =>leafletFG.addLayer(layer));
})
}
}
What might I be doing wrong (or even better, any way I can achieve this)?
Hope this will help you.First,it's not recommended to use this.setState in _onFeatureGroupReady,it will lead to multiple render in map.May be transfer it to componentDidMount which is invoked before the map rendered.And about the return in _onFeatureGroupReady,it's not exactly a bug, but it will return undefined.
_onFeatureGroupReady = (ref) => {
console.log('_onFeatureGroupReady');
console.log(ref);
if(ref===null) {
return;
}
this._editableFG = ref;
// populate the leaflet FeatureGroup with the geoJson layers
if(this.state.data) {
console.log('importing service area from state');
let leafletGeoJSON = new L.GeoJSON(this.state.data);
let leafletFG = this._editableFG.leafletElement;
leafletGeoJSON.eachLayer( layer =>leafletFG.addLayer(layer));
}else if(this.props.data) {
console.log('importing service area from props');
console.log(this.state.data);
let leafletGeoJSON = new L.GeoJSON(this.state.data);
console.log(leafletGeoJSON);
let leafletFG = this._editableFG.leafletElement;
console.log(leafletFG);
leafletGeoJSON.eachLayer( layer =>leafletFG.addLayer(layer));
}
}
Then,about the Map.The latitude and longitude in coordinates of center and coordinates are opposite.So ,maybe the coordinates you set in getGeoJson() is wrong.
<Map center={[37.79,-122.45]} zoom={13} zoomControl={false}>
<FeatureGroup ref={ (reactFGref) => {this._onFeatureGroupReady(reactFGref);} }>
...
</FeatureGroup>
</Map>
function getGeoJson():
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-122.45,
37.79
],
[
-122.42999999999999,
37.79,
],
[
-122.42999999999999,
37.77
],
[
-122.45,
37.77
],
[
-122.45,
37.79
]
]
]
}
}
And,here is my result.

How can i make two objects out of one object, dividing them by a value in the object with lodash

Consider this object, with two channels with NL language and one with EN language:
[
{
"name": "De Redactie",
"channels": [
{
"name": "headlines",
"pubDate": "2017-05-15 09:15:00",
"language": "nl",
"items": [
]
},
{
"name": "headlines English",
"pubDate": "2017-05-14 18:05:00",
"language": "en",
"items": [
]
},
{
"name": "politiek",
"pubDate": "2017-05-14 20:11:00",
"language": "nl",
"items": [
]
}
]
}
]
How can i divide them so that i can get this result:
[
{
"name": "De Redactie",
"channels": [
{
"name": "headlines",
"pubDate": "2017-05-15 09:15:00",
"language": "nl",
"items": [
]
},
{
"name": "politiek",
"pubDate": "2017-05-14 20:11:00",
"language": "nl",
"items": [
]
}
]
}
{
"name": "De Redactie",
"channels": [
{
"name": "headlines English",
"pubDate": "2017-05-14 18:05:00",
"language": "en",
"items": [
]
}
]
}
]
Mind you that this is dummyData. The actual data can contain x amount of one language and y amount of the second or third or fourth ...
I have tried looking in the lodash documentation for the correct combination of functions. Also tried various complex forEach structures, but could not wrap my head around it.
Preferably a solution with lodash or typescript, as i'm working in Angular 4.
Iterate the array with Array#map. For each object, extract the array of channels using destructuring with object rest. Iterate the channels using Array#reduce and group channels with the same language to a Map. Convert back to an array by spreading the Map's values iterator.
Create an array of objects, by mapping them and assigning the group as the channels prop of the object. Flatten the array by spreading into Array#concat:
const data = [{"name":"De Redactie","channels":[{"name":"headlines","pubDate":"2017-05-15 09:15:00","language":"nl","items":[]},{"name":"headlines English","pubDate":"2017-05-14 18:05:00","language":"en","items":[]},{"name":"politiek","pubDate":"2017-05-14 20:11:00","language":"nl","items":[]}]}];
const result = [].concat(...data.map(({ channels, ...rest }) => {
const channelGroups = [...channels.reduce((m, channel) => {
m.has(channel.language) || m.set(channel.language, []);
m.get(channel.language).push(channel);
return m;
}, new Map()).values()];
return channelGroups.map((channels) => ({
...rest,
channels
}));
}));
console.log(result);
way with lodash:
const res = _.chain(arr)
.flatMap(item => _.map( // get array of channels with parent name
item.channels,
channel => _.assign({}, channel, { parentName: item.name })
))
.groupBy('language') // group channels by language
.values() // get channel arrays for each lang
.map(langArrs => ({ // set finished structure
name: _.first(langArrs).parentName, // get name for lang channels
channels: _.omit(langArrs, ['parentName']) // set channels without parent name
}))
.value();

angular-schema-form default, hidden values

I want to build a (section of a) form which produces the following output:
{
...
offers: {
context: "http://schema.org",
minPrice: 3
}
...
}
The catch is, context should always be present - the only field the user gets to manipulate is minPrice. Immediately, a hidden field with a value comes to mind. So here's the schema definition:
$scope.schema = {
...
offers: {
type: 'object',
properties: {
minPrice: {
type: 'number'
}
}
}
...
};
And here the form definition:
$scope.form = [
...
{
key: 'offers',
type: 'fieldset',
items: [
{
key: 'offers.minPrice',
type: 'number'
},
{
key: 'offers.context',
type: 'hidden',
default: 'http://schema.org'
}
]
}
...
];
However, observing the generated model it's obvious the entry context is not present. I have successfully used a combination of type: 'hidden' and default with a tabarray, but I just can't get it right with an object. I am using version 0.8.13 of angular-schema-forms - the latest at the time of this writing.
I'd appreciate any insights, thanks.
You must include context and it's default value within the schema in that version.
I expect that your issue relates to a bug which should have been fixed in the alphas for v1.0.0
It should work with:
Schema
{
"type": "object",
"properties": {
"offers": {
"type": "object",
"properties": {
"minPrice": {
"type": "number"
},
"context": {
"type": "string",
"default": "http://schema.org"
}
}
}
}
}
Form
[
{
"type": "fieldset",
"items": [
{
"key": "offers.minPrice",
"type":"number"
},
{
"key": "offers.context",
"type": "hidden",
"notitle": true
}
]
}
]

Resources