I'm trying to load some json file in a DropdownList from react-widgets. When I load the json file the data type looks like this:
Map {size: 1, _root: ArrayMapNode, __ownerID: undefined, __hash: undefined, __altered: false}
__altered
:
false
__hash
:
undefined
__ownerID
:
undefined
_root
:
ArrayMapNode
size
:
1
__proto__
:
KeyedIterable
While the Dropdown component (from react-widgets) needs an array! So It makes this error:
Failed propType: Invalid prop `data` of type `object` supplied to `DropdownList`,
expected `array`. Check the render method of `Uncontrolled(DropdownList)`.
I can't load the json file directly and I have to use ajax to load it (or technically I can but it's a huge file and each time the user click on the dropdown list it takes couple of seconds to load the data from file). How can I convert this to an array?
P.S. The json file looks like this:
{
"items":[
{
"id": "aaa",
"name": "english"
},
{
"id": "aab",
"name": "Swedish"
},
]
}
I think you're looking for something along the lines of:
var dropdownList = jsonObject.items.map((item, i) => {
return (
<option key={i} val={item.id}>{item.name}</option>
);
})
The Array.prototype.map function simply goes over a list and produces a new list of the same size but with changes based on the modifier/callback function.
Update based on comment:
Based on the docs for DropdownList, you have two options for passing data to the list: a flat array of item names, or a list of objects with specific keys for the item name and value.
Option 1: flat list of item names
var itemNames = jsonObject.items.map((item) => item.name );
Option 2 : list of objects
var items = jsonObject.items.map((item) => {
return {
textField: item.name,
valueField: item.id
}
});
The benefit to using the second option would be when someone selects one of the items, the event that is created with point to the val attribute of the HTML <option>. This is useful for you especially since your ids and names are not the same. An example:
Option 1 (from above):
<DropwdownList
data={itemNames}
onSelect: (event) => {
// Will give the `val` attribute set by DropdownList
// This might be the item name, or it might be something unique to DrowdownList
console.log(event.target.value);
}
/>
Option 2 (from above):
<DropwdownList
data={items}
onSelect: (event) => {
// Will give the `valueField` attribute you set, which for you is the item's `id` field
// This might be the item name, or it might be something unique to DrowdownList
console.log(event.target.value);
}
/>
Related
I am trying to edit the description box or 'tooltip' of an infographic I am creating to show specific data. I am able to access the first item in the array named 'data' using the following code:
tooltip: {
customContent: (title, data) => {
const data1 = data[0]
console.log(data1)
return `<div>${data1}</div>`
},
}
See how this displays in the infographic and console:
However when trying to access an item in this object, in my case, 'name' using the following code:
tooltip: {
customContent: (title, data) => {
const data1 = data[0].name
console.log(data1)
return `<div>${data1}</div>`
},
}
I get the following error shown in the image below:
Does anyone have any ideas of how to overcome this? I am using the antdesign graphing library.
Thanks!
I have an array like so:
reportData = [
{status: "Resolved", type: Placement of bins},
{status: "Assigned", type: Placement of bins},
{status: "Active", type: Sewerage}
]
Now this is what I am trying to do. I want to make as many checkboxes as the count of reportData array but also remove the duplicated values, like in this case, I want "Placement of bins" only once (one checkbox). So overall according to the array there should be only 2 checboxes, but I'm getting three because obviously there are 3 objects in the array.
{
reportData.map((obj) => {
return (
<FormControlLabel
value="type"
control={<Checkbox color="primary" />}
label={obj.type}
labelPlacement="end"
/>
)
})
}
Is there some way to first sort out the duplicated array of objects and maybe then I can map it?
Here is what I would do,
const mapped = reportData.map((obj, index) => obj.type);
const filtered = mapped.filter((type, index) => mapped.indexOf(type) === index )
Here is what happened, map function made a new array called mapped that has the all types you had in reportData including duplicates.
filter filtered the duplicates as; array.indexOf(element) returns index of the first element that matches. Here, 'Placement of bins' is in 0 and 1 indexes. So the iterations be like true false true since in first iteration it is 0 === 0, in second: it's 0 === 1 and in third it's 2===2. So filtered array only gets the elements of index 0 and 2
And then using the filtered array to map to get checkboxes.
You could use lodash method _.uniqBy, it is available in the current version of lodash 4.17.2.
Example:
_.uniqBy([{status:"Resolved", type:'Placement of bins'},
{status:"Assigned", type:'Placement of bins'},
{status:"Active", type:'Sewerage'}], 'type');
// => [{status: "Resolved", type: "Placement of bins"}, {status: "Active", type: "Sewerage"}]
More info: https://lodash.com/docs/#uniqBy
I have a rich text editor field that accepts an embedded block where the content type contains a reference link to another content type.
Like this:
content (rich text field)
- group (embedded block)
- group-items (reference field)
- item 1 (referenced content)
- item 2 (referenced content)
How can I get the referenced content items using #contentful/rich-text-react-renderer?
I currently have this:
import { MARKS, BLOCKS } from '#contentful/rich-text-types';
import { documentToReactComponents } from '#contentful/rich-text-react-renderer';
const options = {
renderNode: {
[BLOCKS.EMBEDDED_ENTRY]: (node) => {
console.log(node);
return true;
}
},
renderText: text => text.replace('!', '?'),
};
Which gives me a bunch of id's but not of the field data for the entries which is what I really want.
content: []
data:
target: {sys: {…}}
__proto__: Object
nodeType: "embedded-entry-block"
content: []
data:
target:
sys: {id: "c13cBu2W6nOkQMx6bsvqCE5", type: "Link", linkType: "Entry"}
__proto__: Object
__proto__: Object
nodeType: "embedded-entry-block"
__proto__: Object
There where 2 problems I was running into here.
Firstly coccasionally Gatsby's cache will cause issues retriving new data from contentful and as such you may only get sys not fields. Which is what was happening to me.
Just delete .cache and rerun yarn run dev and it should be good.
Secondly to get multiple contentTypes with enter blocks this can be achieved by looking for the Entry blocks sys.id. This way you can create different components to handle various content types.
[BLOCKS.EMBEDDED_ENTRY]: (node) => {
const fields = node.data.target.fields;
switch (node.data.target.sys.contentType.sys.id) {
case 'group-item':
return <div>
<GroupItem name={fields.name['en-US']} />
</div>
default:
return <div>Fallback Element</div>
}
handleBeaconChange = (beacons) => {
this.setState({
beacons
});
};
this.state = {
name: '',
color: [],
description: '',
beacons: []
};
<Select.Async
multi={true}
className="margin-select"
value={this.state.beacons}
loadOptions={getBeacons}
onChange={this.handleBeaconChange}/>
[![This is the problem I'm facing actually
I had used react-select and using that I'm using multi-select functionality.
Now the Problem is I can select multiple items but it's showing the complete object in the array rather than only the values.
When I used simpleValue attribute it passes only value but not as a kind of element in an array but as a string separated by ",(comma)" than other string
What I want is the value of all the items selected in an array]2]2
To achieve expected result of getting array values use below option
var obj = this.state.beacons;
var x = obj.map(function(k,v){
return v
})
console.log(x)
https://codepen.io/nagasai/pen/NjwWqo?editors=1111
I have a dropdown with list of states which I am getting through services.In JSON I get list of states with id and label. For ex. id:NJ,label:New Jersey. I have a different response coming from backend which gives me id of 5 states-
ex:
"filters": [
{
"name": "listedStates",
"includedCodes": [
"AZ",
"NJ",
"IN",
"OH",
"WI"
]
}
to populate the list of entire US states in the dropdown, I am iterating like this-
this.addressService.getStates().subscribe(
(data) => {
console.log(data);
if (data) {
//filter with filters array
data.states.forEach(i => {
console.log(data.states);
this.newBaseStatesList.push({ 'value': i.id, 'text': i.label });
console.log(this.newBaseStatesList);
});
}
},
(error) => {
//console.log("An error occurred ");
}
);
Right now my dropdown is getting populated with all the state items in the array whereas I would want to display only 5 states in the dropdown mentioned in the filters array. The problem here is the response I am getting from backend has only ids not the labels and the dropdown should contain the labels values. So I have to somehow map these codes with the states array in such a way that these 5 states get filtered and populated.
My object is in format-
{
id:NJ,
label:New Jersey
}
I would like to check with the state codes in filters array with the states array and display the respective labels. Right now, the entire states are getting populated instead of the 5 states mentioned in the filters array.
You can achieve using as below
this.filters.forEach((filter)=>{
filter.includedCodes.forEach((code)=>{
this.newBaseStatesList.push(_.takeWhile(this.data.states, { 'id': code}))'
});
})
Note:I am using Lodash.
I am not sure the syntax that your service returns for the this.data.states so work need to on it based on the sample json