How to push array inside a object with arrays in React js? - reactjs

I have an issue,
I have a select control component, which has options, inside options I'm adding array of options by mapping array staticPosts.
My code:
<SelectControl
label={__("Choose Static Block Page to show above header", "pirezmeta")}
onChange={ (value) => props.onChangeStaticContent(value) }
options={props.staticPosts && props.staticPosts.map(post =>
({value: post.id, label: post.title}))}
value={props.staticContent}
/>
Everything is fine, except I want to add empty option first, something like: {value: 0, label: "No value"}
How can I do it, can you help me, please?

A lot is going on in that prop. I'd declare the array above, separately - include the first {value: 0, label: "No value"} item, then add in the other mapped items:
const options = [
{value: 0, label: "No value"},
...props.staticPosts?.map(
post => ({value: post.id, label: post.title})
)
];
// ...
<SelectControl
label={__("Choose Static Block Page to show above header", "pirezmeta")}
onChange={ (value) => props.onChangeStaticContent(value) }
options={props.staticPosts && options}
value={props.staticContent}
/>
You could also put the combined array into state on mount or when the props change.

Related

Dynamically use React Component based on data in an object

I'm creating this menu as a fun project in React, and I've finished the code to display/style the components, so now I'm setting it up to be dynamic and generate the menu based on a passed set of data. My React project routes like this:App /→Tab /→Various components based on data.
The plan is to have a menu (App/) contain potentially multiple Tab / of various inputs, such as date, text, number, range, etc. Let's say I use this dataset as an example:
elements: [
{
type: 'number',
text: 'Some Text Label',
fields: [
{
text: 'Some Text',
min: 0,
max: 50,
value: 25,
},
{
text: 'Some Text',
min: 25,
max: 75,
value: 50,
},
],
},
{
type: 'text',
text: 'Some Text Label',
fields: [
{
text: 'Some Text',
value: 'Some Text Placeholder',
},
],
},
{
type: 'number',
text: 'Some Text Label',
fields: [
{
text: 'Some Text',
min: 0,
max: 100,
value: 50,
},
],
},
]
Within the Tab / component, I'd want to look through the elements to find the type of one element, then use the component that is ready for that element (for example, type:number, I would use Number / and then pass the fields as a prop to that component.
Something like this:Number fields={insertdatahere}/>
I'm a total beginner when it comes to react, but I've tried a few ways myself and I feel like I'm just missing something because nothing is working. I was considering just having all the Components manually placed inside the tab component and having them set as Display: None unless an element is present for that type. Thanks for any advice.
Here's a Code sandbox which illustrates one way you could get started.
The basic idea is to define a component for each type of field (text, number, ...) and make a lookup. A function component is like any other value in Javascript - you can store it in an array or an object.
In this case I've defined TextDisplay and NumberDisplay:
const TextDisplay = ({ text, value }) => (
<li>
<h4>{text}</h4>
<input value={value} />
</li>
);
const NumberDisplay = ({ text, min, max, value }) => (
<div>
<h4>{text}</h4>
<input type="number" min={min} max={max} value={value} />
</div>
);
const ComponentForType = {
text: TextDisplay,
number: NumberDisplay
};
Then there's a bit of machinery for displaying the lists of elements in the definition, and the list of fields in each element.
Hopefully that can give you something to play around with. There's a bit of weird syntax in there like the spread operator, and everything gets complicated once you want to make the values editable, but this could be a starting point.

Objects are not valid as a React child (found: object with keys {name}). If you meant to render a collection of children, use an array instead

I am having trouble on posting the lists of data in my table, I hope you guys can help me with this issue, this is the error i am getting Error: Objects are not valid as a React child (found: object with keys {name}). If you meant to render a collection of children, use an array instead.
const columns = [
{
name: "name",
label: "Name",
options: {
filter: true,
sort: true,
}
},
{
name: "dateregistered",
label: "Date Registered",
options: {
filter: true,
sort: false,
}
},
{
name: "department",
label: "Department",
options: {
filter: true,
sort: false,
}
},
];
const data = [
posts.map(post => [{name: 'post.firstname', dateregistered: 'post.date', department: 'post.department'}])
];
return (
<>
<MUIDataTable
title={"Deactivated Users"}
data={data}
columns={columns}
options={options}
/>
</>
)
I see two problems in your data constant. The first one, the .map method returns an array, so there is no need to wrap that value inside an array keys []. The other problem is that you are wrapping the .map return state object in array keys too, that is why the error of creating an object is displayed, because you are returning arrays inside the main mapped array [[{ name: ... }], [{ name: ... }]].
So basically the solution for your issue would be:
const data = posts.map(post => ({name: 'post.firstname', dateregistered: 'post.date', department: 'post.department'}))
Where the parenthesis allows the map method to directly return the object.
The issue is that data is being created as an array in an array in an array. This is why when you try const data = posts.map(post => ...) the error persists, as there is still an array in an array. After you try the above, also re-write
post => [{name: 'post.firstname', dateregistered: 'post.date', department: 'post.department'}]
to
post => ({name: 'post.firstname', dateregistered: 'post.date', department: 'post.department'})
(Changing the square brackets to round)
P.S When you map over posts to build the data, you build a object with the the key "name" and the value "'post.firstname'". That value is a string literal and not accessing some other JS object (It will make "post.firstname" the value for all the post's. Same goes for the other keys.

Custom data attributes on Fluent UI dropdown

I have a requirement to add custom data attributes to the Fluent UI dropdown.
In javascript/html I could add them like this.
option data-passign="true" data-minpt="3" data-maxpt="6" value="7">Data Quality</option
Can someone help me achieve this in Fluent UI + React?
In FluentUI/React, it's much easier than that, no need for data- attributes, you can just add your custom data directly to the options list (and get it back in the event handlers, or as the selected value if you are using "controlled" scenario). Means, if you don't have a specific requirement to store additional item data in the HTML data attributes for "something else" (like ui-automation tool), then you could go with something like this (note the data property):
const YourComponent = (props) => {
const options = [
{ key: '7',
text: 'Data Quality',
data: { passign: true, minpt: 3, maxpt: 7 }
},
{ key: '42',
text: 'Weather Quality',
data: { passign: true, minpt: 100500, maxpt: 42 }
},
];
const onChange = (evt, item) => {
const itemData = item.data;
console.log(item.key, item.text, itemData);
};
return (
<Dropdown
label="Select something"
options={options}
defaultSelectedKey='7'
onChange={onChange}
/>
);
}
If you want a "controlled" control instead (this one is "uncontrolled"), check out the sample page for the Dropdown:
https://developer.microsoft.com/en-us/fluentui#/controls/web/dropdown

react-select wont display default value

I am trying to display a default value in react-select based on an array of values. I have confirmed that the value is equal to the value I am comparing against. I have looked through this post, this post, this post, this post, this post and this post. Despite the similarities, the defaultValue will still not set. I have confirmed by loggin the result of my comparators that they are the same, both in uppercase, both strings.
My Select element is
<Select
name="disposition"
classNamePrefix="select"
options={statusOptions}
ref={selectInputRefPlan}
styles={singleStylesRowComp}
defaultValue={statusOptions.filter(
({ value }) => value.value === lead.disposition
)}
/>
and my array is
const statusOptions = [
{ value: "HOT", label: i18n._(t`HOT`) },
{ value: "WIP", label: i18n._(t`WIP`) },
{ value: "LOST", label: i18n._(t`LOST`) },
{ value: "DNC", label: i18n._(t`DNC`) },
{ value: "WON", label: i18n._(t`WON`) },
{ value: "NEW", label: i18n._(t`NEW`) },
];
I am testing against the value and not the label, so translation issues won't arise. when i log the response, value.value === 'NEW' and lead.disposition === 'NEW', however, the defaultValue will not set. I have also tried the prop value, as well as having read through the 6 or 7 similar posts. Is there a simple syntax error? or something else I am missing?
Here is a sandbox link that demonstrates the issue
The error is in your filter function. You decompose value, and then access value.value. This is undefined.
Instead, take the option argument without decomposition, and access option.value.
<Select
name="disposition"
classNamePrefix="select"
options={statusOptions}
ref={selectInputRefPlan}
styles={singleStylesRowComp}
defaultValue={statusOptions.filter((option) => option.value === lead.disposition)}
/>;

react-semantic-redux-form selectField multiple

I am attempting to use react-semantic-redux-form SelectField with the multiple options so a user can select multiple options and if there is one already set then this should show as checked.
I am also using redux-form with semantic0ui-react.
I am getting an error attempting to include multiple selections.
My include statement is:
import { SelectField } from "react-semantic-redux-form";
My state is:
state = {
relationships: ["some entry"],
relationshipOptions: [],
};
The element code is:
<Grid.Column>
<Field
component={SelectField}
name="relationships"
label="Your Relationships"
options={relationshipOptions}
multiple
placeholder="Select to add a relationship"
/>
I get the error as below
Dropdown `value` must be an array when `multiple` is set. Received type: `[object String]`.
in Dropdown
The way you have relationshipOptions is wrong, it is supposed array of objects,
const relationshipOptions = [
{ key: "single", value: "single", text: "single" },
{ key: "married", value: "married", text: "married" }
];
Here is the working example, Code Sandbox
Also if you have single, married in array. You can do something like this,
let relationshipOptions = ["single", "married"].map((x) => {
return ({
key: x,
value: x,
text: x
});
});

Resources