how to create Dynamic pickers inside loop in react-native? - react-native

This is my steps:
The Json code:
"features": [
{
"name": "size",
"selected": null,
"values": [
{
"value": "40",
"label": "40",
},
{
"value": "41",
"label": "41",
}
]
},
{
"label": "color",
"selected": "gray",
"values": [
{
"value": "gray",
"label": "gray"
},
{
"value": "black",
"label": "black",
}
]
}
]
Step2: define state
constructor(props) {
super(props);
this.state ={selectedDropDownValue:[]};
}
step3:
main render:
render{
return(
{this.printPickers()}
);
}
and
printPickers(){
const listItems = data.map((obj,index) =>
<Item picker key={'mykey1' + index}>
<Picker
selectedValue={(this.state.selectedDropDownValue[obj.label]) ?this.state.selectedDropDownValue[obj.label] : obj.selected}
onValueChange={(itemValue, itemIndex, itemName) =>this.pickerChange(itemIndex,itemValue,obj.name)}
>
{
obj1.values.map( (v)=>{
return <Picker.Item key={'mykey2' + index} label={v.label} value={v.value} />
})
}
</Picker>
</Item>
);
return (<View>{listItems}</View>);
}
and finally:
pickerChange(itemIndex,itemValue,itemName){
this.setState({
selectedDropDownValue: Object.assign(this.state.selectedDropDownValue, {[itemName]: itemValue})
});
}
My problem I can not change options of each pickers by touching them but with console.log(this.state.selectedDropDownValue), I get right data.
My problem I can not change options of each pickers by touching them but with console.log(this.state.selectedDropDownValue), I get right data.

There is some mismatch in json data. Either both should have a key label or name.
So suppose both items have key as label then you need to update your pickerChange function call like this:
this.pickerChange(itemIndex,itemValue,obj.label)

Related

Add items for dropdown in RNPickerSelect in React Native

i am getting array of objects from api.
The data looks like this.
Array [
Object {
"code": 230,
"name": "טרגט",
"themeColor": "#009fe8",
},
Object {
"code": 270,
"name": "קוסל",
"themeColor": "#9c3ab4",
},
Object {
"code": 465,
"name": "מעיין",
"themeColor": "#0bb694",
},
Object {
"code": 485,
"name": "מעיין תיכונים",
"themeColor": "#009fe8",
},
Object {
"code": 700,
"name": "משרד החינוך",
"themeColor": "#9c3ab4",
},
Object {
"code": 701,
"name": "מ.החינוך אולפני",
"themeColor": "#0bb694",
},
Object {
"code": 702,
"name": "חינוך התישבותי",
"themeColor": "#009fe8",
},
Object {
"code": 984,
"name": "לא לגעת -חברת הדגמה ",
"themeColor": "#9c3ab4",
},
]
i want to add a dropdown which contain items as array of objects "name" value from
api.
i am using RNPickerSelect from "react-native-picker-select";
const [selectedComp, setSelectedComp] = useState("");
const changeLanguage = (value) => {
setSelectedComp(value);
};
<RNPickerSelect
placeholder={{ label: i18n.t("SET_LANGUAGE") }}
style={pickerSelectStyles}
onValueChange={(value) => changeLanguage(value)}
items={companyName}
doneText={"בוצע"}
value={selectedComp}
useNativeAndroidPickerStyle={false}
fixAndroidTouchableBug={true}
/>
i want the names for the dropdown list coming from array of object list like below one.
טרגט
קוסל
מעיין
מעיין תיכונים
משרד החינוך
מ.החינוך אולפני
חינוך התישבותי
לא לגעת -חברת הדגמה
How can i add name from array list for dropdown list?
According to the official react-native-picker-select documentation, the data you want to display in the dropdown, should have the keyword label, but you are trying to display name keyword.
The items for the component to render
Each item should be in the following format: {label: 'Orange', value: 'orange', key: 'orange', color: 'orange', inputLabel:
'Orange!'}
label and value are required
Something like this:
<RNPickerSelect
onValueChange={(value) => console.log(value)}
useNativeAndroidPickerStyle={false}
placeholder={{ label: "Select your favourite language", value: null }}
items={[
{ label: "JavaScript", value: "JavaScript" },
{ label: "TypeStript", value: "TypeStript" },
{ label: "Python", value: "Python" },
{ label: "Java", value: "Java" },
{ label: "C++", value: "C++" },
{ label: "C", value: "C" },
]}
/>

How to display names from products in API?

I have an array with two products in it. (later, the list will be more complete, for the moment it's to test the autocomplete that I did like this)
I would like to display the list of the names of these two products in an autocomplete input made with the 'react-native-dropdown-autocomplete' package.
I wanted to initialize name in the state, my concern is that when I ask to display this.state.name it returns me undefined since the two names of the two products are different in the array.
Array [
Object {
"cost": 0,
"created_at": "2020-12-14T15:54:50Z",
"custom_fields": Object {
"_161_": "4137",
"_162_": "48",
"_163_": "10926",
"_164_": "0",
"_165_": "FLY",
"_166_": "2020-12-14T14:54:37.737Z",
"_167_": "2020-12-31T14:54:37.737Z",
"_168_": "0",
"_171_": "0",
"_300_": "412:00",
"_301_": "45.725556|5.081111",
"_302_": "-27.7078990936|-67.0951004028",
"_303_": "Lyon Saint-Exupéry Airport",
"_304_": "Londres/Belén Airport",
"_310_": "60",
},
"description": "",
"family_id": 0,
"id": 1061,
"incl_tax": 0,
"is_visible": 1,
"name": "Lyon Saint-Exupéry Airport (14/12/2020 à 15:54) > Londres/Belén Airport (31/12/2020 à 15:54)",
"photo": "",
"quantity": 0,
"reference": "",
"stock_status": "1",
"tax_rate_id": 0,
"unit": "",
"updated_at": "2020-12-14T15:54:50Z",
"weight": 0,
},
Object {
"cost": 0,
"created_at": "2020-11-15T01:38:08Z",
"custom_fields": Object {
"_161_": "1373",
"_162_": "30",
"_163_": "4680",
"_164_": "0",
"_165_": "FLY",
"_166_": "2020-11-21T00:37:00.000Z",
"_167_": "2020-11-29T00:37:00.000Z",
"_168_": "0",
"_171_": "0",
"_300_": "190:00",
"_301_": "43.6539083949|-79.65785399079999",
"_302_": "-22.285699844399996|-62.7136993408",
"_303_": "Tarten Heliport",
"_304_": "Santa Victoria Airport",
"_310_": "-480",
},
"description": "",
"family_id": 0,
"id": 896,
"incl_tax": 0,
"is_visible": 1,
"name": "Tarten Heliport (2020-11-21 at 16:37) > Santa Victoria Airport (2020-11-29 at 16:37)",
"photo": "",
"quantity": 0,
"reference": "",
"stock_status": "1",
"tax_rate_id": 0,
"unit": "FLY",
"updated_at": "2020-11-15T01:38:08Z",
"weight": 0,
},
]
I would like some help figuring out how I can display the product names.
I understood that my error comes from the fact that the API returns several objects (= several products with different names), whereas I have coded so as to manage only one product.
I need some help and explanation please, I'm running around in circles, lost in my code and, frankly, a little desperate.
I want to thank you for any help and explanation.
Thank you
My code :
class Tickets extends Component {
constructor(props) {
super(props);
this.state = {
Press: false,
hasCameraPermission: null,
reference: '',
name:'',
lastScannedUrl:null,
eventSelected: false,
displayArray: []
};
}
initListData = async () => {
let list = await getProducts(1);
if (list) {
this.setState({
displayArray: list,
reference: list.reference,
name: list.name
});
}
// console.log('name dans initListData =', list.name)
// console.log('reference dans initListData =', list.reference)
};
async UNSAFE_componentWillMount() {
this.initListData();
};
componentDidMount() {
this.getPermissionsAsync();
}
getPermissionsAsync = async () => {
const { status } = await Permissions.askAsync(Permissions.CAMERA);
this.setState({ hasCameraPermission: status === "granted" });
};
handleBarCodeScanned = ({ type, data }) => {
this.setState({ Press: false, scanned: true, name: data });
this.props.navigation.navigate('ProductDetails', {name : parseInt(this.state.state.name)})
};
renderBarcodeReader = () => {
const { hasCameraPermission, scanned } = this.state;
if (hasCameraPermission === null) {
return <Text>{i18n.t("scan.request")}</Text>;
}
if (hasCameraPermission === false) {
return <Text>{i18n.t("scan.noaccess")}</Text>;
}
return (
<View
style={{
flex: 1,
...StyleSheet.absoluteFillObject
}}
>
<Camera
onBarCodeScanned={scanned ? undefined : this.handleBarCodeScanned}
barCodeScannerSettings={[Camera.Constants.Type.qr]}
style={{flex:1}}
/>
{scanned && (
<Button
title={"Tap to Scan Again"}
onPress={() => this.setState({ scanned: false })}
disabled={this.state.selectedItem===null}
/>
)}
</View>
);
}
handleSelectItem(item, index) {
const {onDropdownClose} = this.props;
onDropdownClose();
this.setState({eventSelected: true})
//console.log(item);
}
render() {
const { hasCameraPermission, scanned, Press } = this.state;
let marker = null;
const {scrollToInput, onDropdownClose, onDropdownShow} = this.props;
console.log('displayArray', this.state.displayArray, 'name', this.state.name)
console.log('this.state retourne', this.state)
return (
<View style={{flex:1}}>
<View style={{width: "100%", zIndex: 100}}>
<Autocomplete
key={shortid.generate()}
containerStyle={{margin: 0, padding: 0, borderBottomColor: 'transparent',}}
inputStyle={{ width: '80%', borderWidth: 1, backgroundColor: '#FFF', opacity: 0.9, borderColor: '#F78400'}}
placeholder={i18n.t("tickets.event")}
placeholderColor="#F78400"
pickerStyle={styles.autocompletePicker}
scrollStyle={styles.autocompleteScroll}
scrollToInput={ev => {}}
handleSelectItem={(item, id) => this.handleSelectItem(item, id)}
onDropdownClose={() => onDropdownClose()}
onDropdownShow={() => onDropdownShow()}
data={this.state.name}
minimumCharactersCount={2}
highlightText
valueExtractor={item => item.name}
rightContent
rightTextExtractor={item => item.properties}
/>
</View>
{this.state.eventSelected ? (
<View>
{this.renderBarcodeReader()}
</View>
) : (
<Text style={{ top: '33%', zIndex:100, color: 'red', fontStyle: 'italic', fontSize: 18}}>{i18n.t("tickets.warning")}</Text>
)}
</View>
);
}
}
export default Tickets;
What i have found from your Code. I guess the problem is here
data={this.state.name}
Here you have to pass your array.
data={Your_array}

Flatlist inside Flatlist : get data from the parent Flatlist

Im rendering multiple slides and each slide have a list of items.
so I had to render a Flatlist inside Flatlist like this:
<FlatList
ref={(list) => this.ref= list}
data={this.state.buttons} // parent data
keyExtractor={(item) => item.id.toString()}
...
getItemLayout={(data, index)=> (
{
length: wp('100%'),
offset: wp('100%') * index,
index,
borderWidth: 1, borderColor: 'red',
}
)}
showsHorizontalScrollIndicator={false}
renderItem={({item}) => {
let parentData = item;
let myData = this.state.listGifts + '.' + parentData.name;
console.warn('data ', parentData, item);
return (
<View style={{width: wp('100%')}}>
{
this.state.isLoading ?
<ActivityIndicator size='large' style={Styles.styleAI} color={Colors.mainYellow}/>
:
<FlatList
contentContainerStyle={Styles.flatContent}
data={myData}
// keyExtractor={(item) => item.id.toString()}
renderItem={this.renderItem}
removeClippedSubviews={true}
extraData={this.state}
/>
}
</View>
)
}
}
extraData={this.state}
/>
I fetch two JSON :
this.state.buttons >
{
"message": "",
"success": true,
"Category": [
{
"id": 2,
"name": "Peinture"
},
{
"id": 3,
"name": "Cuisine"
},
{
"id": 4,
"name": "Outils"
},
{
"id": 5,
"name": "Electromenager"
}
]
}
this.state.giftsList >
{
"message": "OK",
"success": true,
"Peinture": [
{
"idCadeau": 2,
"Cadeau": "Cadeau1",
"Unites": "100",
},
{
"idCadeau": 3,
"Cadeau": "Cadeau2",
"Unites": "1000",
},
{
"idCadeau": 4,
"Cadeau": "Cadeau3",
"Unites": "50",
}
],
"Cuisine": [
{
"idCadeau": 5,
"Cadeau": "Cadeau4",
"Unites": "200",
},
{
"idCadeau": 6,
"Cadeau": "Cadeau5",
"Unites": "2500",
}
],
"Outils": [
{
"idCadeau": 7,
"Cadeau": "Cadeau6",
"Unites": "100",
}
],
"Electromenager": [
{
"idCadeau": 9,
"Cadeau": "Cadeau7",
"Unites": "500",
}
]
}
for the second Flatlist (the child), I try to get data like this (see code below) :
let myData = this.state.listGifts + '.' + parentData.name;
...
data={myData}
but it doesn't work ! I comment this // keyExtractor={(item) => item.idCadeau.toString()} because it give an error and then it give me an empty list .
**
what I want is set data like this :
**
data={this.state.listGifts.Peinture}
data={this.state.listGifts.Cuisine}
data={this.state.listGifts.Outils}
...
If this.state.listGifts is an object then I believe you mean to do something like this:
let myData = this.state.listGifts[parentData.name];

How to list two different data in the same FlatList?

I would just like to use a FlatList to list annotation and editedAnnotation, but I can't list both. As shown below, it is listing annotation only.
My state and API:
const [cards, setCards] = useState([]);
useEffect(() => {
async function loadCards() {
const response = await api.get('annotation');
setCards(response.data);
}
loadCards();
}, []);
My list:
<FlatList
data={cards.Annotation}
keyExtractor={call => String(call.id)}
renderItem={({item: call}) => (
<Card {...call}/>
)}
/>
API Return:
{
"Annotation": [
{
"id": 1,
"dateIn": "2019-12-13T18:54:39.0248433+00:00",
"message": "test1",
"statusId": 1,
"symbolId": 5,
"symbol": {
"id": 5,
"status": "start",
}
},
{
"id": 2,
"dateIn": "2019-12-13T14:23:10.6056632+00:00",
"message": "test2",
"statusId": 1,
"symbolId": 2,
"symbol": {
"id": 2,
"status": "end",
}
}
],
"editedAnnotation": [
{
"Annotation": {
"id": 3,
"dateIn": "2019-12-13T19:28:10.6056632+00:00",
"message": "test3",
"statusId": 1,
"symbolId": 2,
"symbol": {
"id": 2,
"status": "start",
}
}
},
"id": 1,
"dateEdit": "2019-12-13T22:27:23.6273816+00:00",
"newMessage": "test3 updated",
"annotationId": 3
}
]
}
You could use spread operator to mix both lists into only one list.
<FlatList
data={[...(cards.Annotation || []), ...(cards.editedAnnotation || [])]}
keyExtractor={call => String(call.id)}
renderItem={({item: call}) => (
<Card {...call}/>
)}
/>
Or you could try using SectionList.

RNPickerSelect trying to display selection from mapping data of objects in an array

I am using RNPickerSelect from the library "react-native-picker-select", but cant seem to display the selection by mapping objects of an array stored in one of my state.
I tried using the same way to map objects of an array like how I would when I'm trying to display the data by wrapping in simple components but I'm getting an "Type Error. undefined is not an object (evaluating this.state.selectedItem.label".
I have declared and initialize bankResponseArray : [] within my react native class. And the API call to fetch data was successful, the state "bankResponseArray" was inserted with the data of
[
Object {
"__v": 0,
"_id": "5cb411e06f34961204003b79",
"bank_code": "RHB",
"country": "5cb04a7e23479e39e495f2b6",
"created_date": "2019-04-15T05:08:48.769Z",
"name": "RHB",
"status": true,
},
Object {
"__v": 0,
"_id": "5cb42d6635ab9132e0e0b994",
"bank_code": "Maybank",
"country": "5cb04a7e23479e39e495f2b6",
"created_date": "2019-04-15T07:06:14.701Z",
"name": "Maybank",
"status": true,
},
Object {
"__v": 0,
"_id": "5cd4e8b0c4022833942eafe0",
"bank_code": "HongLeong",
"country": "5cb04a7e23479e39e495f2b6",
"created_date": "2019-05-10T02:57:52.130Z",
"name": "HongLeong",
"status": true,
},
Object {
"__v": 0,
"_id": "5cd4ee47c4022833942eafe2",
"bank_code": "testbankcode",
"country": "5cbfc9c99b7d064464592948",
"created_date": "2019-05-10T03:21:43.534Z",
"name": "testbank",
"status": true,
},
]
And below is how my RNPickerSelect component looks like and how I'm trying to map the data from "bankResponseArray" :-
<RNPickerSelect
placeholder={{}}
useNativeAndroidPickerStyle={false}
items={this.state.bankResponseArray.map(obj =>
[{
label: obj.name,
value: obj._id,
color: "rgba(77,38,22,1)"
}]
)}
onValueChange={(value, index) => {
this.setState({
bankID: value
});
}}
onClose={() => {
// this._changeGender()
}}
style={{ ...pickerSelectStyles }}
value={this.state.businessType}
ref={el => {
this.inputRefs.picker = el;
}}
hideIcon={Platform.OS === "ios" ? false : true}
doneText={translate("common_done")}
// disabled={!canSubmit}
/>
The expected results were to have the RNPickerSelect display 4 selections which are "RHB, Maybank, HongLeong, testbank". But currently the way I'm trying to map my array to the RNPickerSelect is getting the error of "Type Error. undefined is not an object (evaluating this.state.selectedItem.label".
You should to return an object directly and not an array.
You can use like this:
items={this.state.bankResponseArray.map(obj => (
{
key: obj._id,
label: obj.name,
value: obj._id,
color: "rgba(77,38,22,1)",
}))}