undefined is not an object when using sectioned multi select react native - reactjs

I have a piece of code that creates a sectioned multi select component based on https://github.com/renrizzolo/react-native-sectioned-multi-select.
This is my code:
import React, { useState } from 'react';
import {I18nManager,View,Text,SafeAreaView,Image,SectionList,TouchableOpacity,TextInput,ScrollView,useWindowDimensions,Linking} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import SectionedMultiSelect from 'react-native-sectioned-multi-select';
export function SellWithUsFirstScreen3(props){
const items = [
{
name: "Fruits",
id: 0,
children: [{
name: "Apple",
id: 10,
},{
name: "Strawberry",
id: 17,
},{
name: "Pineapple",
id: 13,
},{
name: "Banana",
id: 14,
},{
name: "Watermelon",
id: 15,
},{
name: "Kiwi fruit",
id: 16,
}]
},
{
name: "Gems",
id: 1,
children: [{
name: "Quartz",
id: 20,
},{
name: "Zircon",
id: 21,
},{
name: "Sapphire",
id: 22,
},{
name: "Topaz",
id: 23,
}]
},
{
name: "Plants",
id: 2,
children: [{
name: "Mother In Law\'s Tongue",
id: 30,
},{
name: "Yucca",
id: 31,
},{
name: "Monsteria",
id: 32,
},{
name: "Palm",
id: 33,
}]
},
]
const [selectedItems,setselectedItems] = useState([]);
onSelectedItemsChange = (theitem) => {
setselectedItems(prevState => [...prevState, theitem]);
}
console.log(selectedItems);
/////////
return (
<SafeAreaView style={{flex:1,backgroundColor:'white'}}>
<View style={styles.container}>
<View>
<SectionedMultiSelect
items={items}
uniqueKey='id'
subKey='children'
selectToggleIconComponent={<Icon name='folder' />}
dropDownToggleIconUpComponent={<Icon name='chevron-up' />}
dropDownToggleIconDownComponent={<Icon name='chevron-down' />}
selectedIconComponent={<Icon name='heart' />}
selectText='Choose some things...'
showDropDowns={true}
readOnlyHeadings={true}
onSelectedItemsChange={this.onSelectedItemsChange}
selectedItems={selectedItems}
IconRenderer={Icon}
/>
</View>
</View>
</SafeAreaView>
);
}
I get this error:
TypeError: undefined is not an object (evaluating 'item[subKey]').
I tried several code changes but I still can't get the same result as the original author video images.
Any help please?

I think your problem is that you need double quotation marks around the strings so uniqueKey="children" for each of them. Also there is no this. so you must make onSelectedItemsChange={this.onSelectedItemsChange} into onSelectedItemsChange={onSelectedItemsChange}

Related

Modifying select for product variation in React Js

In a small ecommerce project (sourcing data from WooCommerce) in ReactJs i have a variable product
Besides all the product data i got two array object representing the product variations, one contains all the available attribute and options:
nodes: Array(3)
0:
id: "d2VpZ2h0OjMxOldlaWdodA=="
name: "Weight"
options: Array(2)
0: "250gr"
1: "500gr"
position: 0
variation: true
visible: true
1:
id: "cm9hc3Q6MzE6Um9hc3Q="
name: "Roast"
options: Array(3)
0: "Light"
1: "Medium"
2: "Dark"
position: 1
variation: true
visible: true
2:
id: "cGFja2FnaW5nOjMxOlBhY2thZ2luZw=="
name: "Packaging"
options: Array(2)
0: "Card"
1: "Tin"
position: 2
variation: true
visible: true
I save this one in a state and use it to build the select (3 select in this case)
then i have an array of object which contans all the available combinations, with price, id and so on:
nodes: Array(5)
0:
attributes:
nodes: Array(3)
0: {id: "NDB8fHdlaWdodHx8MjUwZ3I=", name: "weight", value: "250gr"}
1: {id: "NDB8fHJvYXN0fHxNZWRpdW0=", name: "roast", value: "Medium"}
2: {id: "NDB8fHBhY2thZ2luZ3x8Q2FyZA==", name: "packaging", value: "Card"}
id: "cHJvZHVjdF92YXJpYXRpb246NDA="
price: "€7,00"
variationId: 40
1:
attributes:
nodes: Array(3)
0: {id: "Mzh8fHdlaWdodHx8NTAwZ3I=", name: "weight", value: "500gr"}
1: {id: "Mzh8fHJvYXN0fHxEYXJr", name: "roast", value: "Dark"}
2: {id: "Mzh8fHBhY2thZ2luZ3x8VGlu", name: "packaging", value: "Tin"}
length: 3
id: "cHJvZHVjdF92YXJpYXRpb246Mzg="
price: "€12,00"
variationId: 38
2:
attributes:
nodes: Array(3)
0: {id: "Mzd8fHdlaWdodHx8NTAwZ3I=", name: "weight", value: "500gr"}
1: {id: "Mzd8fHJvYXN0fHxNZWRpdW0=", name: "roast", value: "Medium"}
2: {id: "Mzd8fHBhY2thZ2luZ3x8VGlu", name: "packaging", value: "Tin"}
length: 3
id: "cHJvZHVjdF92YXJpYXRpb246Mzc="
price: "€12,00"
variationId: 37
3:
attributes:
nodes: Array(3)
0: {id: "MzZ8fHdlaWdodHx8NTAwZ3I=", name: "weight", value: "500gr"}
1: {id: "MzZ8fHJvYXN0fHxMaWdodA==", name: "roast", value: "Light"}
2: {id: "MzZ8fHBhY2thZ2luZ3x8VGlu", name: "packaging", value: "Tin"}
id: "cHJvZHVjdF92YXJpYXRpb246MzY="
price: "€12,00"
variationId: 36
4:
attributes:
nodes: Array(3)
0: {id: "MzR8fHdlaWdodHx8MjUwZ3I=", name: "weight", value: "250gr"}
1: {id: "MzR8fHJvYXN0fHxMaWdodA==", name: "roast", value: "Light"}
2: {id: "MzR8fHBhY2thZ2luZ3x8Q2FyZA==", name: "packaging", value: "Card"}
length: 3
id: "cHJvZHVjdF92YXJpYXRpb246MzQ="
price: "€7,00"
variationId: 34
Basically, when i select something on any select, the other select shoould filter based on the avaialble variations: if i select 250gr as weight, the Dark Roast and the Tin Packaging sould be removed from their select since they arent combinable with 250gr; if i switch back to 500gr (or to "no option selected") they should reappear in the same place as they were before.
on the basic WooCommerce product page it already works this way (you can check its behaviour here: https://shop.popland.it/prodotto/coffee-bean/) but replicating it in ReactJs its harder than i was thinking.
At the moment im stuck on loop that generate the select with an empty onChange handler:
const [attr, setAttr] = useState(product.attributes);
<div>
{attr.nodes.map((attribute, l) => {
return (
<div key={l}>
<span>{attribute.name}</span>
<select
id={attribute.name}
onChange={handleChange}
data-attribute_name={`attribute_${attribute.name}`}
>
<option>Select option</option>
{attribute.options.map((option, o) => {
return (
<option key={o} value={option}>
{option}
</option>
);
})}
</select>
</div>
);
})}
</div>
Any suggetion/help on how to go on from here?
here is my solution.
/src/hooks.js
import { useState } from "react";
import { filterVariations, formatVariations } from "./helpers";
export function useVariations(product) {
const [state, setState] = useState({});
const filteredVariations = filterVariations(
product?.variations?.nodes,
state,
);
const formatedVariations = formatVariations(
filteredVariations,
product?.variations?.nodes,
);
return [formatedVariations, state, setState];
}
/src/helpers.js
export function filterVariations(variations, state) {
if (Object.keys(state).length === 0) {
return variations;
}
return Object.keys(state)?.reduce((accStateVars, currStateVar) => {
return accStateVars.reduce((accVars, currVar) => {
const filteredAttrsByName = currVar?.attributes?.nodes?.filter(
(attr) => currStateVar === attr?.name,
);
const withSelected = currVar?.attributes?.nodes?.findIndex(
(attr) => attr?.attributeId === state?.[currStateVar]?.value,
);
return [
...accVars,
{
attributes: {
nodes:
withSelected >= 0
? currVar?.attributes?.nodes
: filteredAttrsByName,
},
},
];
}, []);
}, variations);
}
export function formatVariations(filteredVariations, variations) {
const defaultSelects = variations?.reduce(
(accVars, currVar) => ({
...accVars,
...currVar?.attributes?.nodes?.reduce(
(accAttrs, currAttr) => ({ ...accAttrs, [currAttr.name]: {} }),
{},
),
}),
{},
);
return filteredVariations.reduce((accVars, currVar) => {
const filteredAttrs = currVar?.attributes?.nodes?.reduce(
(accAttrs, currAttr) => {
const exists =
0 <=
accVars[currAttr.name]?.options?.findIndex(
(option) => option.value === currAttr.attributeId,
);
return {
...accAttrs,
[currAttr.name]: {
placeholder: currAttr.label,
options: exists
? accVars[currAttr.name]?.options || []
: [
...(accVars[currAttr.name]?.options || []),
{ label: currAttr.value, value: currAttr.attributeId },
],
},
};
},
{},
);
return { ...accVars, ...filteredAttrs };
}, defaultSelects);
}
/src/App.js
import "./styles.css";
import Select from "react-select";
import { useVariations } from "./hooks";
const product = {
variations: {
nodes: [
{
attributes: {
nodes: [
{
name: "pa_size",
attributeId: 254,
id: "NTY5MHx8cGFfc2l6ZXx8MTItc3BlYWtlcg==",
label: "Size",
value: '12" Speaker',
},
{
name: "pa_color",
attributeId: 304,
id: "NTY5MHx8cGFfY29sb3J8fGdyYXBoaXRl",
label: "Color",
value: "Graphite",
},
{
name: "pa_flavor",
attributeId: 320,
id: "NTY5MHx8cGFfZmxhdm9yfHxnb2xk",
label: "Flavor",
value: "Gold",
},
{
name: "pa_pallet",
attributeId: 336,
id: "NTY5MHx8cGFfcGFsbGV0fHxncmVlbg==",
label: "Pallet",
value: "Green",
},
],
},
},
{
attributes: {
nodes: [
{
name: "pa_size",
attributeId: 255,
id: "NTY4Nnx8cGFfc2l6ZXx8MTAtc3BlYWtlcg==",
label: "Size",
value: '10" Speaker',
},
{
name: "pa_color",
attributeId: 67,
id: "NTY4Nnx8cGFfY29sb3J8fGJlaWdl",
label: "Color",
value: "Beige",
},
{
name: "pa_flavor",
attributeId: 320,
id: "NTY4Nnx8cGFfZmxhdm9yfHxnb2xk",
label: "Flavor",
value: "Gold",
},
{
name: "pa_pallet",
attributeId: 337,
id: "NTY4Nnx8cGFfcGFsbGV0fHxwZWFjaA==",
label: "Pallet",
value: "Peach",
},
],
},
},
{
attributes: {
nodes: [
{
name: "pa_size",
attributeId: 255,
id: "NTY4N3x8cGFfc2l6ZXx8MTAtc3BlYWtlcg==",
label: "Size",
value: '10" Speaker',
},
{
name: "pa_color",
attributeId: 439,
id: "NTY4N3x8cGFfY29sb3J8fGZhdGFsLWFwcGxl",
label: "Color",
value: "Fatal Apple",
},
{
name: "pa_flavor",
attributeId: 319,
id: "NTY4N3x8cGFfZmxhdm9yfHx2YW5pbGxh",
label: "Flavor",
value: "Vanilla",
},
{
name: "pa_pallet",
attributeId: 336,
id: "NTY4N3x8cGFfcGFsbGV0fHxncmVlbg==",
label: "Pallet",
value: "Green",
},
],
},
},
{
attributes: {
nodes: [
{
name: "pa_size",
attributeId: 254,
id: "NTY4OHx8cGFfc2l6ZXx8MTItc3BlYWtlcg==",
label: "Size",
value: '12" Speaker',
},
{
name: "pa_color",
attributeId: 67,
id: "NTY4OHx8cGFfY29sb3J8fGJlaWdl",
label: "Color",
value: "Beige",
},
{
name: "pa_flavor",
attributeId: 320,
id: "NTY4OHx8cGFfZmxhdm9yfHxnb2xk",
label: "Flavor",
value: "Gold",
},
{
name: "pa_pallet",
attributeId: 337,
id: "NTY4OHx8cGFfcGFsbGV0fHxwZWFjaA==",
label: "Pallet",
value: "Peach",
},
],
},
},
{
attributes: {
nodes: [
{
name: "pa_size",
attributeId: 254,
id: "NTY4OXx8cGFfc2l6ZXx8MTItc3BlYWtlcg==",
label: "Size",
value: '12" Speaker',
},
{
name: "pa_color",
attributeId: 436,
id: "NTY4OXx8cGFfY29sb3J8fGJlbGdyYXZlcw==",
label: "Color",
value: "Belgraves",
},
{
name: "pa_flavor",
attributeId: 319,
id: "NTY4OXx8cGFfZmxhdm9yfHx2YW5pbGxh",
label: "Flavor",
value: "Vanilla",
},
{
name: "pa_pallet",
attributeId: 336,
id: "NTY4OXx8cGFfcGFsbGV0fHxncmVlbg==",
label: "Pallet",
value: "Green",
},
],
},
},
],
},
};
export default function App() {
const [selects, state, setState] = useVariations(product);
function onChange(select, value) {
const newState = {
...state,
[select]: { ...value, name: select },
};
if (!value) {
delete newState[select];
}
setState(newState);
}
return (
<div className="App">
{Object.keys(selects).map((select) => (
<Select
isClearable
key={selects[select].placeholder}
placeholder={selects[select].placeholder}
// value={state[select]}
onChange={(o) => onChange(select, o)}
options={selects[select].options}
/>
))}
</div>
);
}
Playground

React component only rendering one item in my object

So I have a react component set up to map through all the items in my array to display them on the page. I'm importing my component onto my homepage and passing the object as a prop from the imported component. However, when I load the page, only one item from the object is being rendered. I'm not entirely sure if I'm passing my object correctly. Any help would be appreciated! Code is below.
This is my Modal component. I'm mapping through the listGroupArray that has a spread operator with my data that is being passed from the home page.
export default function ModalButton({ setData, title, arrayData, dataTitle }) {
const [show, setShow] = useState(false);
const [button, setButton] = useState("Choose...")
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
const listGroupArray = [{...arrayData}]
const changeButton = e => setButton(e)
return (
<>
<h5 className="inputFont text-center">{title}</h5>
<Button style={{ backgroundColor: "black", opacity: "1", color: "white", borderColor: "red" }} variant="primary" className="w-100 mb-4 inputFont" onClick={handleShow}>
{button}
</Button>
<Modal show={show} onHide={handleClose}>
<Modal.Header closeButton className="modal-bg inputFont">
{dataTitle}
</Modal.Header>
<Modal.Body className="modal-bg">
<ListGroup>
{listGroupArray.map(item => (
<ListGroup.Item key={item.id} className="modal-bg">
<Button
style={{
backgroundColor: "black",
opacity: ".8",
color: "white",
borderColor: "red",
}}
className="inputFont w-100"
name={item.name}
value={item.value}
onClick={(e) => {
setData(item.value);
changeButton(item.name);
handleClose();
}}
>
{item.name}
</Button>
</ListGroup.Item>
))}
</ListGroup>
</Modal.Body>
</Modal>
</>
);
}
This is my homepage where I'm passing the array data as an object. I'm pretty sure this is where I'm going wrong. When I load the page, the component should render all the data in the object, however it's only rendering the last data, Classics.
<Modal title="Genre"
dataTitle="Pick A Genre"
setData={setGenrelist}
arrayData={
{
id: 1,
name: "Action and Adventure",
value: "10673,10702,11804,11828,1192487,1365,1568,2125,2653,43040,43048,4344,46576,7442,75418,76501,77232,788212,801362,899,9584"
},
{
id: 2,
name: "Musicals",
value: "13335,13573,32392,52852,55774,59433,84488,88635"
},
{
id: 3,
name: "Sci-Fi",
value: "1492,108533,11014,1372,1568,1694,2595,2729,3327,3916,47147,4734,49110,50232,52780,52849,5903,6000,6926,852491"
},
{
id: 4,
name: "Fantasy",
value: "9744"
},
{ id: 5,
name: "Thrillers",
value: "10306,10499,10504,10719,11014,11140,1138506,1321,1774,3269,43048,46588,5505,58798,65558,6867,75390,78507,799,852488,8933,98911,9147,972"
},
{
id: 6,
name: "Anime",
value: "10695,11146,2653,2729,3063,413820,452,6721,9302,7424"
},
{
id: 7,
name: "Children and Family",
value: "10056,27480,27950,28034,28083,28233,48586,5455,561,6218,6796,6962,78120,89513,783"
},
{
id: 8,
name: "Comedies",
value: "1009,10256,10375,105,10778,11559,11755,1208951,1333288,1402,1747,17648,2030,2700,31694,3300,34157,3519,3996,4058,4195,43040,4426,4906,52104,52140,52847,5286,5475,5610,56174,58905,59169,61132,61330,6197,63092,63115,6548,711366,7120,72407,7539,77599,77907,78163,78655,79871,7992,852492,869,89585,9302,9434,9702,9736"
},
{
id: 9,
name: "Documentaries",
value: "10005,10105,10599,1159,15456,180,2595,2616,2760,28269,3652,3675,4006,4720,48768,49110,49547,50232,5161,5349,55087,56178,58710,60026,6839,7018,72384,77245,852494,90361,9875"
},
{
id: 10,
name: "Dramas",
value: "11,11075,11714,1208954,1255,12995,13158,2150,25955,26009,2696,2748,2757,2893,29809,3179,31901,34204,3653,3682,384,3916,3947,4282,4425,452,4961,500,5012,52148,52904,56169,58755,58796,59064,6206,62235,6616,6763,68699,6889,711367,71591,71591,72354,7243,7539,75459,76507,78628,852493,89804,9299,9847,9873,5763"
},
{
id: 11,
name: "Sports",
value: "180,25788,4370,5286,7243,9327"
},
{
id: 12,
name: "Horror",
value: "10695,10944,1694,42023,45028,48303,61546,75405,75804,75930,8195,83059,8711,89585"
},
{
id: 13,
name: "Romance",
value: "29281,36103,502675"
},
{
id: 14,
name: "Classics",
value: "10032,11093,13158,29809,2994,31273,31574,31694,32392,46553,46560,46576,46588,47147,47465,48303,48586,48744,76186"
}
}
/>
screenshot of the homepage
This image shows the component only rendering one data item which is Classics. Any advice on how to get all data rendered would be greatly appreciated! Thanks!
The error is in how you referenced the arrayData and the problematic curly brackets you used on an array. In your JSX code, you have a syntax error, you are supposed to enclose arrays in curly brackets, or better still just separate them to their own variable.
Your JSX should then look something like this:
function JSX(props) {
const arrayData = [
{
id: 1,
name: "Action and Adventure",
value:
"10673,10702,11804,11828,1192487,1365,1568,2125,2653,43040,43048,4344,46576,7442,75418,76501,77232,788212,801362,899,9584",
},
{
id: 2,
name: "Musicals",
value: "13335,13573,32392,52852,55774,59433,84488,88635",
},
{
id: 3,
name: "Sci-Fi",
value:
"1492,108533,11014,1372,1568,1694,2595,2729,3327,3916,47147,4734,49110,50232,52780,52849,5903,6000,6926,852491",
},
{
id: 4,
name: "Fantasy",
value: "9744",
},
{
id: 5,
name: "Thrillers",
value:
"10306,10499,10504,10719,11014,11140,1138506,1321,1774,3269,43048,46588,5505,58798,65558,6867,75390,78507,799,852488,8933,98911,9147,972",
},
{
id: 6,
name: "Anime",
value: "10695,11146,2653,2729,3063,413820,452,6721,9302,7424",
},
{
id: 7,
name: "Children and Family",
value:
"10056,27480,27950,28034,28083,28233,48586,5455,561,6218,6796,6962,78120,89513,783",
},
{
id: 8,
name: "Comedies",
value:
"1009,10256,10375,105,10778,11559,11755,1208951,1333288,1402,1747,17648,2030,2700,31694,3300,34157,3519,3996,4058,4195,43040,4426,4906,52104,52140,52847,5286,5475,5610,56174,58905,59169,61132,61330,6197,63092,63115,6548,711366,7120,72407,7539,77599,77907,78163,78655,79871,7992,852492,869,89585,9302,9434,9702,9736",
},
{
id: 9,
name: "Documentaries",
value:
"10005,10105,10599,1159,15456,180,2595,2616,2760,28269,3652,3675,4006,4720,48768,49110,49547,50232,5161,5349,55087,56178,58710,60026,6839,7018,72384,77245,852494,90361,9875",
},
{
id: 10,
name: "Dramas",
value:
"11,11075,11714,1208954,1255,12995,13158,2150,25955,26009,2696,2748,2757,2893,29809,3179,31901,34204,3653,3682,384,3916,3947,4282,4425,452,4961,500,5012,52148,52904,56169,58755,58796,59064,6206,62235,6616,6763,68699,6889,711367,71591,71591,72354,7243,7539,75459,76507,78628,852493,89804,9299,9847,9873,5763",
},
{
id: 11,
name: "Sports",
value: "180,25788,4370,5286,7243,9327",
},
{
id: 12,
name: "Horror",
value:
"10695,10944,1694,42023,45028,48303,61546,75405,75804,75930,8195,83059,8711,89585",
},
{
id: 13,
name: "Romance",
value: "29281,36103,502675",
},
{
id: 14,
name: "Classics",
value:
"10032,11093,13158,29809,2994,31273,31574,31694,32392,46553,46560,46576,46588,47147,47465,48303,48586,48744,76186",
},
];
return (
<Modal
title="Genre"
dataTitle="Pick A Genre"
setData={(data) => console.log(data)}
arrayData={arrayData}
/>
);
}
The next bug you had was in using the spread operator. While arrays are technically objects in JavaScript they can't be spread with curly braces. This [{...arrayData}] is syntactically incorrect. Instead it should be [...arrayData]. With these in place, your code should run correctly.
I made a sandbox of your code in a working state for reference, check it out here:
https://codesandbox.io/s/young-snowflake-efqwk?file=/src/ModalButton.js:877-883

React ant design table cell collapse issue

Im using my react type script project for ant design table
i want to know how to do that following image like as table, im search any tutorial but not seen anything, any one know how to do that correctly.
code sand box here
Thanks
image here
code here
class App extends React.Component {
columns: any = [
{
title: "Name",
dataIndex: "name",
key: "name"
},
{
title: "Age",
dataIndex: "age",
key: "age"
},
{
title: "Address",
dataIndex: "address",
key: "address"
},
{
title: "Tags",
key: "tags",
dataIndex: "tags"
},
{
title: "Action",
key: "action"
}
];
data: any = [
{
key: "1",
name: "John Brown",
age: 32,
address: "New York No. 1 Lake Park",
tags: ["nice", "developer"]
},
{
key: "2",
name: "Jim Green",
age: 42,
address: "London No. 1 Lake Park",
tags: ["loser"]
},
{
key: "3",
name: "Joe Black",
age: 32,
address: "Sidney No. 1 Lake Park",
tags: ["cool", "teacher"]
}
];
render() {
return <Table columns={this.columns} dataSource={this.data} />;
}
}
You want to create 2 sub rows in each row, but only for some columns. you can use rowspan for this.
you can duplicate your rows (row1-row1-row2-row2-row3-row3-...), and put the subrow values in them (row1_subrow1-row1_subrow2-row2_subrow1-row2_subrow2-...), then use rowspan for the columns you want to expand (like Section and Name in your image), and expand the odd rows and collapse the even rows for this columns.
the full code : (Codesandbox Demo)
import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Table } from "antd";
let multiRowRender = (value, row, index) => {
const obj = {
children: value,
props: {}
};
if (index % 2 === 0) {
obj.props.rowSpan = 2;
}
if (index % 2 === 1) {
obj.props.rowSpan = 0;
}
return obj;
};
const columns = [
{
title: "Number",
dataIndex: "number"
},
{
title: "Issue",
dataIndex: "issue"
},
{
title: "Name",
dataIndex: "name",
render: multiRowRender
},
{
title: "Section",
dataIndex: "section",
render: multiRowRender
}
];
let data = [
{
key: "1",
name: "John Brown",
issues: [32, 100],
numbers: [18889898989, 545054],
section: "sec 1"
},
{
key: "2",
name: "Jim Green",
issues: [42, 50],
numbers: [18889898888, 1420054],
section: "sec 2"
}
];
let data2 = [];
data.forEach(d => {
data2.push({ ...d, issue: d.issues[0], number: d.numbers[0] });
data2.push({
...d,
issue: d.issues[1],
number: d.numbers[1],
key: d.key + "-row2"
});
});
data = data2;
ReactDOM.render(
<Table columns={columns} dataSource={data} bordered />,
document.getElementById("container")
);
Codesandbox Demo

AntD Table Columns do not render leading or trailing whitespace in their values

I'm displaying values from a database in an AntD Table that can lead or end with whitespace and the whitespaces are not being rendered. I've forked a simple Table example to show the issue:
https://codesandbox.io/s/agitated-frog-obmh1
What is the correct way to get AntD to stop trimming extra whitespace in the values?
I've included the code below for posterity:
import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Table } from 'antd';
const columns = [
{
title: 'Name',
dataIndex: 'name',
filters: [
{
text: 'Joe',
value: 'Joe',
},
{
text: 'Jim',
value: 'Jim',
},
{
text: 'Submenu',
value: 'Submenu',
children: [
{
text: 'Green',
value: 'Green',
},
{
text: 'Black',
value: 'Black',
},
],
},
],
// specify the condition of filtering result
// here is that finding the name started with `value`
onFilter: (value, record) => record.name.indexOf(value) === 0,
sorter: (a, b) => a.name.length - b.name.length,
sortDirections: ['descend'],
},
{
title: 'Age',
dataIndex: 'age',
defaultSortOrder: 'descend',
sorter: (a, b) => a.age - b.age,
},
{
title: 'Address',
dataIndex: 'address',
filters: [
{
text: 'London',
value: 'London',
},
{
text: 'New York',
value: 'New York',
},
],
filterMultiple: false,
onFilter: (value, record) => record.address.indexOf(value) === 0,
sorter: (a, b) => a.address.length - b.address.length,
sortDirections: ['descend', 'ascend'],
},
];
const data = [
{
key: '1',
name: ' John Brown ', // WHITESPACE ADDED HERE
age: 32,
address: ' New York No. 1 Lake Park ', // WHITESPACE ADDED HERE
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
{
key: '4',
name: 'Jim Red',
age: 32,
address: 'London No. 2 Lake Park',
},
];
function onChange(pagination, filters, sorter, extra) {
console.log('params', pagination, filters, sorter, extra);
}
ReactDOM.render(<Table columns={columns} dataSource={data} onChange={onChange} />, document.getElementById('container'));
Seems there is no such an option to stop trimming. However, you can replace whitespace(\u0020) to (\u00a0) to get the same view:
const data = [{
key: '1',
name: '\u00a0\u00a0\u00a0\u00a0\u00a0John Brown\u00a0\u00a0\u00a0\u00a0',
age: 32,
address: 'London No. 2 Lake Park'
}]

How can I build model data?

I was asked to create a mini amazon web app and as model data, I was told to use the below code. const items is products sold in the mini amazon and const promotion is a seperate data for all promotion each user get. Where do I store itemsAvailable.js and promotion.js so that I can fetch those in react components?
// itemsAvailable.js
const items = [
{
id: '123',
title: 'product1',
coverImage: 'public.jpg',
price: 20,
score: 20,
},
{
id: '123123',
title: 'product2',
coverImage: 'public2.jpg',
price: 30,
score: 30,
},
];
// promotion.js
const promotion = [
{
type: 'sale',
title: '30%',
rate: 30,
},
];
One way is using state,
constructor(props){
super(props);
this.state = {
item: [{
id: '123',
title: 'product1',
coverImage: 'public.jpg',
price: 20,
score: 20,
},
{
id: '123123',
title: 'product2',
coverImage: 'public2.jpg',
price: 30,
score: 30,
}
],
promotion: [{
type: 'sale',
title: '30%',
rate: 30,
}
]
}
}
Usage,
{
this.state.item.map((item)=>{
<div>{item.id}</div>
....
})
}
Likewise you can use promotion array.

Resources