Reputation: 640
What I need is very simple, in SQL I would say I would merely need a SORT ASCENDING or DESCENDING.
But it has been a while I'm working with GraphQL, AppSync, DynamoDB and React-Native, and I still did not figure out how to sort my output list by name...
I'm using the simple scenario, without React-Native Apollo, just with the Connect component.
My Output list:
class PlantScreenNoApollo extends React.Component {
...
render() {
return (
<View style={{flex:1, flexDirection:"column", justifyContent:"flex-start"}}>
<View style={{flex:1,
flexDirection:"row",
justifyContent:"center",
}}>
<TextInput style={styles.sTextInput}
onChangeText={ (text) => this._updateFilter(text) }
value={this.state.filter}/>
<Ionicons name={"ios-search"} size={30} />
</View>
<View style={{ flex:1,
flexDirection:"column",
justifyContent:"flex-start",
alignContent: "center",
minHeight: "70%",}}>
<Connect query={ this.state.filter!=="" ?
graphqlOperation(queries.listPlants, {
filter: {
name: {
contains: this.state.filter
}
}
})
:
graphqlOperation(queries.listPlants)
}>
{
( { data: { listPlants }, loading, error } ) => {
if(error) return (<Text>Error</Text>);
if(loading || !listPlants) return (<ActivityIndicator />);
return (
<FlatList
data={listPlants.items}
renderItem={({item}) => {
return (
<View style={{borderBottomWidth:1, borderBottomColor:"green", padding:5}}>
<TouchableOpacity onPress={()=>this._onPress(item)}>
<View style={styles.hcontainer}>
<Image source={{uri:this.state.logoURL}}
style={styles.iconImage}
/>
<View style={styles.vcontainer}>
<Text style={styles.textH3}>{item.name}</Text>
<View style={styles.hcontainerflexstart}>
{ item.tea && <Image source={{uri:this.state.teaIconURL}} style={styles.iconImageSmall} />}
{ item.bath && <Image source={{uri:this.state.bathIconURL}} style={styles.iconImageSmall} />}
{ item.insence && <Image source={{uri:this.state.insenceIconURL}} style={styles.iconImageSmall} />}
{ item.children && <Image source={{uri:this.state.childrenIconURL}} style={styles.iconImageSmall} />}
</View>
</View>
<Text style={styles.textP}>{item.description.substr(0,50) + "(...)"}</Text>
</View>
</TouchableOpacity>
</View>
);
}}
keyExtractor={(item, index) => item.id}
/>
);
}
}
</Connect>
</View>
<View style={{flex:1, flexDirection:"column", justifyContent:"flex-start"}}>
...
</View>
</View>
);
};
}
And this is my query description (auto-generated by the model + codegen)
export const listPlants = `query ListPlants(
$filter: ModelPlantFilterInput
$limit: Int
$nextToken: String
) {
listPlants(filter: $filter, limit: $limit, nextToken: $nextToken) {
items {
id
name
description
...
}
nextToken
}
}
All I want is to sort the scan by name.
I tried even to create a secondary index, but it didn't change anything...
Does anyone know the best way to accomplish this?
Upvotes: 1
Views: 3219
Reputation: 421
Change your listPlants resolver to perform a Query instead of a Scan and you can utilize the scanIndexForward boolean to determine if you want to return the results in ascending or descending order based on the index provided (in your case - 'name').
This will require you to index the name attribute in DynamoDB if it is not already.
For more information - look at the Query section in the following documentation:
In particular:
ScanIndexForward
Specifies the order for index traversal: If true (default), the traversal is performed in ascending order; if false, the traversal is performed in descending order.
Items with the same partition key value are stored in sorted order by sort key. If the sort key data type is Number, the results are stored in numeric order. For type String, the results are stored in order of UTF-8 bytes. For type Binary, DynamoDB treats each byte of the binary data as unsigned.
If ScanIndexForward is true, DynamoDB returns the results in the order in which they are stored (by sort key value). This is the default behavior. If ScanIndexForward is false, DynamoDB reads the results in reverse order by sort key value, and then returns the results to the client.
Here's a detailed stackoverflow answer that details this.
Upvotes: 1