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

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.

Related

React native Switch is not working for multiple fields correctly?

React-native switch toggle is not working even though i have set value for each feild separately.Also Its setting value correctly but toggle switch is not reflecting that.I want if user selects 2 field's the switch button should be enabled for that particular field's and others will be disabled.
const SystemInformation = props => {
const [isEnabled, setIsEnabled] = useState(false);
const [selectedFeild, setSelectedFeild] = useState([
{ id: 1, text: "Entry", toggle: false },
{ id: 2, text: "Exit", toggle: false },
{ id: 3, text: "Stay", toggle: false }
]);
const toggleSwitch = type => {
setSelectedFeild(type);
setIsEnabled(previousState => !previousState);
};
const renderWordList = () => {
const wordList = selectedFeild.map((word, i, wordArray) => (
<View key={word.id} style={styles.wordsContainer}>
<TextView>{word.text}</TextView>
<Switch
style={styles.pilgrimsWordSwitch}
onValueChange={toggleValue => {
wordArray[i].toggle = toggleValue;
setSelectedFeild(wordArray);
}}
value={word.toggle}
/>
</View>
));
return wordList;
};
return <View style={styles.container}>{renderWordList()}</View>;
};
export default SystemInformation;
Any lead will be appreciated what i am doing wrong ?

React-admin SelectInput occurs out of range warning

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!

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;
},[]);

FlatList items re-rendering even with React.memo

I am trying to render a list of items in React Native with the FlatList component but every time I fetch new data it re-renders the who list of items even with React.memo.
Here is what my code looks like:
const data = [
{ _id: 1, text: 'Hello World' },
{ _id: 2, text: 'Hello' },
{ ... }
]
const renderItem = ({ item }) => (<Component item={item} />)
const loadMore = () => {
//Fetching data from db and adding to data array
}
<FlatList
data={data}
keyExtractor={item => item._id}
renderItem={renderItem}
onEndReached={loadMore}
removeClippedSubviews={true}
/>
Component.js
const Component = ({ item }) => {
console.log('I am rendering')
return (
<Text>{item.text}</Text>
)
}
const equal = (prev, next) => {
return prev.item.text === next.item.text
}
export default React.memo(Component, equal)
Every time the onEndReached function gets triggered and calls the loadMore function, all FlatList items get re-rendered, it console.log 'I am rendering' every single time and causes the error virtualizedlist you have a large list that is slow to update
Thanks to anyone who can help me!
I don't know why but I fixed it with an if statement in the equal function
//Changing this
const equal = (prev, next) => {
return prev.item.text === next.item.text
}
//To this
const equal = (prev, next) => {
if(prev.item.text !== next.item.text) {
return false;
}
return true
}
Hope this could help someone else.

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)}
/>
}