React-admin SelectInput occurs out of range warning - react-admin

I have SelectInput inside of ReferenceInput
As you can see below,
This is workaround version of code. the selection shows right data and it parses as I expected, however, a out-of-range value **[object Object]** is show. (please see the reference image below)
This is a code snippet of SelectInput component
const AddressSelectInput: FC<AddressSelectInputProps> = (
{
customerId,
source,
...props
}
) => {
const classes = useStyles()
const [choices, setChoices] = useState<InputSourceProps[] | undefined>()
// sorting data from props
useEffect(() => {
if (props.choices) {
const result: InputSourceProps[] | undefined = props.choices?.find(
item => item._id === customerId
)?.addresses?.map((item: UserAddress) => {
let res: InputSourceProps;
res = {
name: item.label,
description: item.place.description,
postalCode: item.place.postalCode,
location: {
lat: item.place.location.lat,
lng: item.place.location.lng
}
}
return res;
})
setChoices(result)
}
}, [props.choices, customerId])
if (!choices) {
return null
}
const optionRenderer = (choice: Place) => `${choice.name} - ${choice.description}`;
return (
<SelectInput
className={classes.selectInputStyle}
label="Addresses suggestion"
choices={choices}
source={source}
optionText={optionRenderer}
optionValue={'name'}
defaultValue=''
parse={(name: string) => choices.find(c => c.name === name)}
/>
)
}
this is parent component of SelectInput:
const RideReferenceAddressInput: FC<RideReferenceInputProps> = ({
source,
label,
customerId,
}) => {
const filterToQuery = (customerId: string) => (filter: string) => ({
$search: filter,
_id: customerId
})
return (
<ReferenceInput
reference="users"
source={source}
filterToQuery={filterToQuery(customerId)}
>
<AddressSelectInput source={source} label={label} customerId={customerId} />
</ReferenceInput>
)
}
Could anyone can help to remove the warning? and why this is warning shows?
Thank you all in advance!

Related

Why is translate not working when I pass it as prop?

Why it is not working ? I get no error...
## MEMO START ##
function isEqual(prev: IMyOrders, next: IMyOrders) {
if(prev.name=== next.name) {
return true;
} else {
return false;
}
}
const Item = ({
name,
t
}: { name: string; t: any; }) => {
return (
<Pressable style={s.item}>
<Text style={s.product_name}>Ordered Date: { t('profile.logged.reviews.created_at', { date: order_date }) }</Text>
</Pressable>
)
};
const MEMO_ITEM = memo(Item, isEqual);
## MEMO END ##
const SettingsMyOrders = () => {
const { t, i18n } = useTranslation();
const renderItem: ListRenderItem<IMyOrders> = ({ item }) => (
<MEMO_ITEM
{...item}
t={t}
/>
);
return (
<FlashList
data={data}
keyExtractor={(item, i) => item.name.toString()}
renderItem={renderItem}
estimatedItemSize={280.7}
/>
)
}
Why it is not working when I put this with memo ? when leave the memo and dont put it as prop then works but thats not the way I want
Try to write your custom are props equal function, because you have props as object. You can find more here -> https://dmitripavlutin.com/use-react-memo-wisely/

`react-native-dropdown-picker` not selecting default value for multiSelect, if list item having selected:true {label:"A", value:1, selected:true}

I am trying to use multiselect feature of react-native-dropdown-picker which is working fine for selecting item, I can select multiple Items and can get its values too, but my problem is I am not able to show defaultValue on screen load.
I am fetching data from server and then trying to show on dropdown-picker
const AccountSelection = (props) => {
const [accountId, setAccount] = useState([])
const [accountList, setAccountList] = useState([])
const [defaultAccount, setDefaultAccount] = useState([])
useEffect(() => {
getAccounts()
}, [])
const getAccounts = () => {
axiosConfig.get('/accounts')
.then((response) => {
if (response.status == 200) {
const accountData = response.data.payload.data
const accountNames = accountData.map((item) => ({ label: item.name, value: item.id, selected: item.id == store.usersDefaultValues.account_id ? true : false }))
setAccountList(accountNames)
setDefaultAccount(accountNames.find(item => item.selected == true ? item.value : null))
}
}
})
.catch((error) => {
console.log("axios error", error);
})
}
return (
<View>
<DropDownPicker
placeholder="Select Account"
value={accountId}
items={accountList}
onChangeItem={(val) => setAccountId(val)}
defaultValue={defaultAccount}
multiple={true}
activeItemStyle={{ backgroundColor: '#F5CCF8' }}
></DropDownPicker>
</View>
)
}
On screen Load I am getting blank dropdown-picker, where it should show 1 Item Selected.
In DropDownPickerProps in react-native-dropdown-picker optional selected key is available but it is not working
items: {
label: any;
value: any;
icon?: () => JSX.Element;
hidden?: boolean;
disabled?: boolean;
selected?: boolean;
}[];
Please share if anyone have solution for this. Thank you.
The defaultValue attribute is not longer supported in react-native-dropdown-picker. If you want to select a default value, you simply need to set the 'value' variable to the default value's value.
You can read more in this issue: https://github.com/hossein-zare/react-native-dropdown-picker/issues/511#issuecomment-1049110163.

remove duplicate error from JSON value React Native

I am trying to pass filtered value from JSON to the parent component, however I've tried using Set but seems the output is still the same. The component that I'm using to render the JSON is picker from native-base. I want to filter out the repeated value in my picker. Greatly appreciated if anyone can help me.
enter image description here
Here's my code.
Picker.js
const DefaultPicker = ({labelItem, pickerWidth, onHandleValue, ...rest}) => {
const context = useContext(WindowContext);
const [selectedValue, setSelectedValue] = useState('-Select-');
const [data, setData] = useState([]);
const {user, setUser} = useContext(AuthContext);
function onNewData() {
if (user) {
user.getIdToken().then((idToken) => {
Axios.get('URL_ENDPOINT', {
headers: {
Authorization: 'Bearer' + idToken,
},
})
.then(({data}) => {
setData(data.features);
// console.log(data.features);
})
.catch((error) => {
console.error(error);
});
});
}
}
useEffect(() => {
const form = onNewData(onNewData);
return form;
}, []);
return (
<PickerWrapper>
<PickerItem
width={pickerWidth}
height="60"
mode="dropdown"
selectedValue={selectedValue}
onValueChange={(itemValue, itemIndex) => {
setSelectedValue({itemValue});
}}>
{Array.from(
new Set(
data.map((value, index) => (
<PickerItem.Item
key={index}
label={value.properties[labelItem]}
value={value.properties[labelItem]}
{...rest}
/>
)),
),
)}
</PickerItem>
</PickerWrapper>
);
};
And here is my parent component
SiteData.js
const SiteData = () => {
const [values, setValues] = useState([]);
const onHandleValue = (params) => {
setValues(params);
console.log(params);
};
return (
<ScrollableView>
<DetailContainer>
<DetailWrapper>
<DetailTitle>Site Data</DetailTitle>
<DetailSubtitle marginTop="10">
Insert new data found during your audit or observation session
</DetailSubtitle>
<DetailSubcontainer>
<DefaultPicker
labelItem={'category'} <-- receive value from child
pickerWidth="100%"
onHandleValue={onHandleValue}
/>
</DetailSubcontainer>
</DetailWrapper>
</DetailContainer>
</ScrollableView>
);
};
UPDATE 1:
I'm using the filter() method so i can create a new array but it returns only one value in the picker list.
const indexData = data.filter(
({category}, index) => {
return (
data.findIndex(
(item) =>
item.category === category,
) === index
);
},
);
The output
enter image description here
I fixed my code by adding this on child component
var setObj = new Set();
var result = data.reduce((acc,item)=>{
if(!setObj.has(item.category)){
setObj.add(item.category,item)
acc.push(item)
}
return acc;
},[]);

React Admin Change field based on related record field

Let's say I have a record called 'assets' which has a column called deducitble. An asset can have one Insurer. The insurer has a boolean field 'allowOtherDeductible'.
When editing the asset, I want the ability to first check if the associated insurer has allowOtherDeductible set to true. If so I'll allow a TextInput for deductible, if false, a SelectInput.
How can I achieve this? I cannot see a way to fetch related record's fields when conditionally rendering fields.
I ended up pulling in all the insurers and loading the asset when the component loaded. Seems a bit inefficient, but I couldn't come up with a better way:
export const AssetEdit = props => {
const dataProvider = useDataProvider();
const [insurers, setInsurers] = useState([]);
const [asset, setAsset] = useState(null);
const [otherDeductible, setOtherDeductible] = useState(false);
useEffect(() => {
dataProvider.getOne('assets', { id: props.id })
.then(({ data }) => {
setAsset(data);
return dataProvider.getList('insurers', { pagination: { page: 1, perPage: 100 } });
})
.then(({ data }) => setInsurers(data))
.catch(error => {
console.log(error)
})
}, [])
useEffect(() => {
if (asset && insurers) {
const selectedInsurer = insurers.find(insurer => insurer.id === asset?.insurer_id);
setOtherDeductible(selectedInsurer?.other_deductible);
}
}, [insurers])
return (
<Edit {...props}>
<SimpleForm>
{otherDeductible &&
<NumberInput
source={'deductible'}
parse={val => dollarsToCents(val)}
format={val => centsToDollars(val)}
/>
}
<FormDataConsumer>
{({ formData, ...rest }) => {
if(!otherDeductible){
return <SelectInput
source="deductible"
parse={val => dollarsToCents(val)}
format={val => centsToDollars(val)}
choices={getDeductibleChoices(formData.insured_value)}
/>
}
}}
</FormDataConsumer>
</SimpleForm>
</Edit>
)
}
I'd write a custom Input taking advantage of the fact that SimpleForm injects the record to all its children:
const DeductibleInput = ({ record }) => {
if (!record) return null;
const { data, loaded } = useGetOne('insurers', record.insured_id);
if (!loaded) return null; // or a loader component
return data.otherDeductible
? <NumberInput
source="deductible"
parse={val => dollarsToCents(val)}
format={val => centsToDollars(val)}
/>
: <SelectInput
source="deductible"
parse={val => dollarsToCents(val)}
format={val => centsToDollars(val)}
choices={getDeductibleChoices(record.insured_value)}
/>
}

react redux set ownProps from the component receiving ownProps

I need to set the height of the ownProps from within the component that has the ownProps. It doesn't seem to update, it is always undefined.
Can it be done?
Here is my code, with the line of code to look at being commented with //////////////////
const mapStateToProps = (state: State, ownProps): Object => ({
searchText: state.product.search.query.locationAutocomplete.searchText,
place: state.product.search.query.locationAutocomplete.place,
searchResults: state.product.search.query.locationAutocomplete.searchResults,
shouldHideResults:
state.product.search.query.locationAutocomplete.shouldHideResults,
height: ownProps.height,
onContentSizeChange: ownProps.onContentSizeChange
})
const mapDispatchToProps = (dispatch: Dispatch<*>): Object => ({
updateSearchQueryPageLocationAutocompleteSearchText: (searchText: string) => {
dispatch(
updateSearchQueryPageLocationAutocompleteSearchText({
searchText: searchText
})
)
},
updateSearchQueryPageLocationAutocompletePlace: (locationPlace: Place) => {
dispatch(
updateSearchQueryPageLocationAutocompletePlace({
locationPlace: locationPlace
})
)
},
getSearchQueryPageLocationAutocompletePlaceDetails: (placeId: number) => {
dispatch(
getSearchQueryPageLocationAutocompletePlaceDetails({ placeId: placeId })
)
},
getSearchQueryPageLocationAutocompleteResults: (text: string) => {
dispatch(getSearchQueryPageLocationAutocompleteResults({ text: text }))
},
updateProductSearchQueryPageIsLoctionListDisplayed: (displayed: boolean) => {
dispatch(updateProductSearchQueryPageIsLoctionListDisplayed(displayed))
},
updateLocationShouldHideResults: (shouldHideResults: boolean) => {
dispatch(updateSearchQueryPageShouldHideLocationResults(shouldHideResults))
}
})
let LocationView = (props: LocationViewProps): Object => {
return (
<Autocomplete
value={props.searchText}
customStyle={autocompleteStyle.customStyle(props.place)}
placeholder={'Location'}
updateValue={props.updateSearchQueryPageLocationAutocompleteSearchText}
updateDataBehindValue={
props.updateSearchQueryPageLocationAutocompletePlace
}
getDataBehindValueDetails={
props.getSearchQueryPageLocationAutocompletePlaceDetails
}
autocompleteResults={props.searchResults}
getSearchQueryPageLocationAutocompleteResults={
props.getSearchQueryPageLocationAutocompleteResults
}
shouldHideResults={props.shouldHideResults}
onListItemSelect={location => {
props.getSearchQueryPageLocationAutocompletePlaceDetails(
location.place_id
)
props.updateSearchQueryPageLocationAutocompleteSearchText(
location.description
)
props.updateLocationShouldHideResults(true)
props.updateProductSearchQueryPageIsLoctionListDisplayed(false)
}}
onContentSizeChange={height => {
console.log(height)
props.height = getHeight(height)}////////////////////////this line///////////////////////
}
onChangeText={text => onChangeText(props, text)}
/>
)
}
const getHeight = height => {
const h = Math.max(60, height)
return h
}
LocationView = connect(
mapStateToProps,
mapDispatchToProps
)(LocationView)
height: ownProps.height,
It's unseless, either you receive your props from the parent <MyComponent height={...} ..., either you pass the props from your store mapStateToProps = (state, ownProps) => ({ height: state..., //here ownProps contains to the props passed to MyComponent, so height={...} })
If you want to change the props passed from the parent, use a handle function like that
handleSetheight = height => this.setState({ height })
return (<Child height={this.state.height} setHeight={this.handleSetHeight}/>)