PREMISE
First my API was a simple endpoint for fetching user chat history but the backend team changed the API to add three params: cursor, limit and searchTerm, and I was asked to implement it in React Native frontend for infinite scrolling using FlatList along with a search feature.
ISSUE
The API has 35 objects but in my implementation as soon as I reach the end of the first batch [limit] rendered no new data is fetched.
My API response
{
"success": true,
"data": {
"sessions": [
{
"id": "6d84c2dd-5386-4a8e-b946-ddd65a2f1dde",
"title": "Yogeshwar chawla+1733847198813",
"userId": "58162f9d-cd92-4fa2-b637-151d7763c0b5",
"personalityId": "381ed434-1b6a-4c68-a19d-3f268e03c5c6",
"personality":"blabla",
chats": [
{
"role": "human",
"content": "According to my steps what should I do next, hiking or cycling?"
},
{
"role": "ai",
"content": "Asity workout t"
}
],
"createdAt": "2024-12-10T16:13:19.937Z",
"updatedAt": "2024-12-10T16:13:19.937Z"
},
{34 same objs}
],
"nextCursor": null
},
"message": "User sessions fetched successfully"
}
CODE
//The states
const {sessionId} = route.params;
const [loading, setLoading] = useState(false);
const [error, setError] = useState();
const [jwtToken, setjwtToken] = useState();
const [listData, setListData] = useState([]);
const [search, setSearch] = useState('');
const [cursor, setCursor] = useState(null);
const [hasMore, setHasMore] = useState(true);
//function to fetch all data
const fetchMyList = async () => {
if (loading || !hasMore) return;
try {
const limit = 15;
setLoading(true);
const token = await AsyncStorage.getItem('jwtToken');
setjwtToken(token);
const listResp = await fetch(
`${BACKEND_URL}/chat/sessions?cursor=${cursor || ''}&limit=${limit}${
search ? `&searchTerm=${search}` : ''
}`,
{
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
},
);
// console.log('list response is', listResp);
const listJSON = await listResp.json();
// console.log('list JSON is', listJSON);
const {success, message} = listJSON || {};
if (!success) {
console.log('error 1');
setError(message || 'An error occurred while fetching data');
} else {
const {sessions, nextCursor} = listJSON.data || {};
console.log('nextCursor is', nextCursor);
if (sessions && sessions.length > 0) {
setListData(prev => [...prev, ...sessions]);
setCursor(nextCursor);
setHasMore(!!nextCursor);
// setListData(sessions);
// setFilteredData(sessions);
} else {
setHasMore(false);
}
}
} catch (error) {
setError(error.message);
} finally {
setLoading(false);
}
};
//functions to use search
const handleSearchChange = text => {
setSearch(text);
setListData([]);
setCursor(null);
setHasMore(true);
};
const clearSearch = () => {
setSearch('');
setListData([]);
setCursor(null);
setHasMore(true);
};
//useEffect to call it immediately as screen mounts or search param changes
useEffect(() => {
fetchMyList();
}, [search]);
//React native code
<View style={styles.searchWrapper}>
<View style={styles.searchContainer}>
<Ionicons
name="search"
size={responsiveFontSize(20)}
color="black"
style={styles.searchIcon}
/>
<TextInput
style={styles.searchInput}
placeholder="Search History"
placeholderTextColor="grey"
value={search}
onChangeText={text => {
handleSearchChange(text);
}}
/>
<TouchableOpacity onPress={clearSearch}>
<Ionicons
name="close"
size={responsiveFontSize(20)}
color="black"
style={styles.cancelIcon}
/>
</TouchableOpacity>
</View>
{loading ? (
<View style={styles.listContainer}>
<SkeletonLoader count={5} />
</View>
) : (
<FlatList
data={listData}
keyExtractor={item => item.id}
renderItem={renderBoxComponent}
contentContainerStyle={styles.listContainer}
showsVerticalScrollIndicator={false}
initialNumToRender={5}
maxToRenderPerBatch={5}
onEndReachedThreshold={0.5}
onEndReached={fetchMyList}
ListFooterComponent={loading ? <SkeletonLoader count={2} /> : null}
/>
)}
Now can someone help me debug this problem or help me fix it?
1
If i am not wrong here cursor means page number, so instead of setting cursor to null default value of cursor should be 0 or 1 according to your api needs and then do an increment in courser by 1 when you reach end of the page by calling onEndReached then you will get next 15 values from session.
But i doubt that api is not giving desired data according to the limit passed as in the response you are providing it already shows 35 objects. So check if limit is working or not.
Anupam Singh Kushwaha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.