Intended outcome:
I'm using react-native and I have a Flatlist that gets it's data from a useQuery hook. I want to call the fetchMore
function when the user reaches the end of the list, to grab the next page of data, and append it to the list.
The useQuery looks like this:
const { data, error, fetchMore } = useDataQuery({
variables: { ids: [id], pageSize: 10 },
fetchPolicy: 'cache-and-network'
})
The Flatlist has props:
onEndReached={loadMore}
onEndReachedThreshold={0.5}
data={data?.mySecretData?.someSecretItems}
and loadMore
that gets called when user reaches end of list:
const loadMore = useCallback(
async ({ distanceFromEnd }) => {
if (data.hasNextPage === false || distanceFromEnd < 0) return
try {
await fetchMore({
variables: { page: data.currentPage + 1 },
updateQuery: (prev, { fetchMoreResult }) => {
if (!fetchMoreResult) return prev
return {
mySecretData: {
someSecretItems: [...prev.mySecretData.someSecretItems, ...fetchMoreResult.mySecretData.someSecretItems],
currentPage: fetchMoreResult.mySecretData.currentPage
}
}
}
})
} catch (e) {
// We always end up here
console.log(e)
}
},
[data, fetchMore]
)
Actual outcome:
The first page of data is rendered in the Flatlist just fine, but trying to call the fetchMore
function when the end of the list is reached yields the following error in the catch:
[TypeError: undefined is not a function (near '...}).finally(function () {...')]
After adding logging to the updateQuery
function, I can see that the next page of data comes back successfully from the request, but we still end up in the catch with the above error. I should also note that the Flatlist displays the new page of data for a brief sub-second before disappearing and going back to only rendering the first page of data.
How to reproduce the issue:
I believe I am able to reproduce this issue on all versions after "@apollo/client": "3.0.0-beta.44",
When my team and I rolled back to this version, things started working normally.
Versions
System:
OS: macOS 10.15.4
Binaries:
Node: 12.16.3 - ~/.nvm/versions/node/v12.16.3/bin/node
Yarn: 1.22.4 - /usr/local/bin/yarn
npm: 6.14.4 - ~/.nvm/versions/node/v12.16.3/bin/npm
Browsers:
Chrome: 83.0.4103.61
Firefox: 57.0.4
Safari: 13.1
npmPackages:
@apollo/client: 3.0.0-beta.44 => 3.0.0-beta.44
@apollo/link-context: ^2.0.0-beta.3 => 2.0.0-beta.3
What version of React Native are you using, and on which platform (ios or android) did you see this happening? Is it possible that this version of React Native does not support/polyfill Promise.prototype.finally
?
@benjamn we are using "react-native": "~0.62.0"
. We are experiencing the issue on both ios and android. And I think you may be on to something there. A team member mentioned that he was debugging a feature in the app and found that a .finally
block was never getting executed. He didn't see any error, but I'm assuming that if he had wrapped it in try catch, it would catch and log the same error I was seeing.
I should also note that we performed an expo eject
a few months back. I'm now wondering if this has caused some versioning issues. In the package.json we have edit: i see that that is just the react-native cli version"react-native": "~0.62.0"
, but when run ./node_modules/.bin/react-native --version
, i get 4.9.0
It might be related to this issue:
Did you find a solution for this? I am running into the exact same issue using fetchMore with FlatList in React Native.
My app is on React Native 0.62.2
I am not sure if I am doing a non-hook query correctly but I am wondering if this error is also similar to our fetchMore finally error that we are seeing.
I am importing the client I use for the ApolloProvider directly into a class component to use via client.query() and I get an error response of:
[TypeError: this.fetchQuery(queryId, options).finally is not a function. (In 'this.fetchQuery(queryId, options).finally(function () {
return _this.stopQuery(queryId);
})', 'this.fetchQuery(queryId, options).finally' is undefined)]
Finally got this fixed if anyone else runs into this error on React Native.
Install core-js and add this line to your index.js file for the app.
import 'core-js/features/promise'
Same exact issue here, adding the polyfill above works but requires me to add one more package to the bundle, so not ideal...
Would there be a better way to fix it?
I use an Apollo Client on the backend for service-to-service, so for me it was the issue that my Pod on Kubernetes cluster was using a Docker environment with a Node 8 it was fixed after I updated it to 12.
Finally got this fixed if anyone else runs into this error on React Native.
Install core-js and add this line to your index.js file for the app.
import 'core-js/features/promise'
Oh man! I was pulling my hair out trying to figure out what was wrong. Had almost given up hope and conceded that Apollo + fetchMore + React Native was just completely broken. Importing the polyfill solved everything though. Thanks a lot. This should probably be added to official docs _somewhere_!
I encountered a similar issue on a react web application where it complains finally()
is not a function in FireFox and IE 11 (no issues in other browsers). My application is fully babel transformed via the babel-loader
when bundled with Webpack though. Below are my @babel/preset-env
options:
{
"targets": {
"edge": "14",
"firefox": "50",
"chrome": "49",
"safari": "10",
"ie": "11"
},
"useBuiltIns": "usage",
"corejs": "3.6",
}
It didn't help. I had to manually add import 'core-js/features/promise'
as mentioned in this thread.
Still an issue, and it's quite dirty to use the import fix when your project is under Expo managed workflow, because index.js isn't accessible. I need to patch expo package in order to access AppEntry.js, which is not very clean.
A fix would be hugely appreciated ! 馃憤
I'm up to some PRs if necessary, but I'd need some clues about how to fix this
Still an issue, and it's quite dirty to use the import fix when your project is under Expo managed workflow, because index.js isn't accessible. I need to patch expo package in order to access AppEntry.js, which is not very clean.
A fix would be hugely appreciated ! 馃憤
I'm up to some PRs if necessary, but I'd need some clues about how to fix this
Hi, I don't like having to use this import either but I use Expo and didn't need to patch the Expo package.
At least in my case, just including the import in the app's root component (App.tsx or App.jsx) was enough for me.
Most helpful comment
Finally got this fixed if anyone else runs into this error on React Native.
Install core-js and add this line to your index.js file for the app.
import 'core-js/features/promise'