Sorting a list by a referenced field react-admin - react-admin

I started using react-admin and is basically works fine. However I have some trouble using the ReferenceField.
The REST API I'm calling returns e.g. the following JSON data:
/language
{
"language": [
{
"id": 0,
"name": "Language #0"
},
{
"id": 1,
"name": "Language #1"
},
{
"id": 2,
"name": "Language #2"
},
{
"id": 3,
"name": "Language #3"
}
]
}
/myreferences
{
"myreferences": [
{
"id": 0,
"langauge": {
"id": 0,
"name": "Language #0"
},
"name": "My reference #0"
},
{
"id": 1,
"langauge": {
"id": 1,
"name": "Language #1"
},
"name": "My reference #1"
},
{
"id": 2,
"langauge": {
"id": 2,
"name": "Language #2"
},
"name": "My reference #2"
}
]
}
And that's how map this in react-admin.
export const LanguageList = props => (
<List
title="Languages"
sort={{ field: "name", order: "ASC" }}
filters={<LanguageFilter/>}
{...props}
>
<Datagrid>
<NumberField source="id" label="ID" />
<TextField source="name" label="Name" />
<EditButton />
</Datagrid>
</List>
);
export const MyReferenceList = props => (
<List
title="My References"
sort={{ field: "name", order: "ASC" }}
filters={<MyReferenceFilter />}
{...props}
>
<Datagrid>
<NumberField source="id" label="ID" />
<TextField source="name" label="Name" />
<ReferenceField source="langauge.id" reference="language" label="Language">
<TextField source="name" />
</ReferenceField>
<EditButton />
</Datagrid>
</List>
);
My problem is that the references are shown correctly but when I click on the column for the referenced language name react-admin sorts by the language's ID instead of its name.
What do I need to adapt so that sorting by name is working?

The <ReferenceField> component accepts a sortBy prop, which specifies the field to use for sorting instead of the source. So in your case, you can write:
<ReferenceField source="language.id" sortBy="language.name" reference="language" label="Language">
<TextField source="name" />
</ReferenceField>
This is explained in the React-admin documentation:
https://marmelab.com/react-admin/Fields.html#referencefield

Related

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.

Section List not displaying

Following the React-Native tutorial and I'm unable to get the data to show.
When I do a console.log my data appears like so:
Array [
Object {
"data": Object {
"address": "8753 2nd Street",
"id": "5507",
"inspection_date": "2019-03-27",
"inspection_time": "07:00:00",
"inspection_time_display": "07.00 AM",
"inspector": "Frank",
},
"key": "5507",
"title": "8753 2nd Street",
},
Object {
"data": Object {
"address": "11445 Paramount ave ",
"id": "5505",
"inspection_date": "2019-03-23",
"inspection_time": "10:30:00",
"inspection_time_display": "10.30 AM",
"inspector": "Fabian Hernandez",
},
"key": "5505",
"title": "11445 Paramount ave ",
},
]
I have the "data" and "title" sections as indicated in most tutorials.
My component is like this:
<Container>
<Header />
<Content>
<SectionList
renderItem={({item, index, section}) => <Text key={index}>{item}</Text>}
renderSectionHeader={({section: {title}}) => (
<Text style={{fontWeight: 'bold'}}>{title}</Text>
)}
sections={this.state.dataSource}
keyExtractor={(item, index) => item + index}
/>
</Content>
</Container>
This is what I think is happening but I'm obviously wrong since something isn't adding up.
Looping through "sections"
renderItem={({item, index, section}) => <Text key={index}>{item}</Text>}
I'm expecting this above to get the "data".
Getting title:
renderSectionHeader={({section: {title}}) => (
<Text style={{fontWeight: 'bold'}}>{title}</Text>
)}
I'm expecting this above to get the "title". What am I missing or doing wrong?
I believe the data key in each of your section objects need to be an array unto itself. Example:
const mySectionedData = [
{
title: 'section 1',
data: [
{address: '123 street', name: 'me'},
{address: '456 street', name: 'you}
]
},
{
title: 'section 2',
data: [
{address: '789 street', name: 'us'}
]
}
]
This then lets you access {title, data} from each of your sections which allows the section list to then render your section header from title, and a list of items from the data array.
Hope that helps!

how to create Dynamic pickers inside loop in 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)

When i am trying to Render data into the table it throws null is not object in React Native

<Table borderStyle={{borderColor: '#C1C0B9'}}>
{
tableData.map((rowData, index) =>
(
<View>
<Row
key={index}
data={rowData}
widthArr={state.widthArr}
style={[styles.row, index%2 && {backgroundColor:
'#F7F6E7'}]}
textStyle={styles.text}
/>
</View>
))
}
</Table>
here is the Json Response data
var tableData = [
{
"activityType": "RUNNING",
"averageHeartRateInBeatsPerMinute": 132,
"comments": "",
"durationInSeconds": 4915,
"id": "2672760140",
"startTimeInSeconds": 1525437416,
"startTimeOffsetInSeconds": -14400,
"summaryId": "2672760140",
},
{
"activityType": "OTHER",
"averageHeartRateInBeatsPerMinute": 106,
"comments": "",
"durationInSeconds": 60,
"id": "2672781872",
"startTimeInSeconds": 1525442382,
"startTimeOffsetInSeconds": -14400,
"summaryId": "2672781872",
},
]
When i am try to map this array into the Row It Throws the Null is not an object error. Could you please suggest the solution to this problem