What is the recommended way for caching ajax requests or using push notifications w/ service workers in a CRA based PWA?
See original GitHub issueI’m using the newest versions of create-react-app and react-scripts.
For a fully functional offline PWA, I would need to cache network requests to show some data while the user is offline, Most tutorials I saw were listening to the fetch event in the service-worker itself using self.addEventListener, but since CRA uses workbox-plugin to autogenerate the service worker as a developer I don’t have access to “self” so I can’t freely listen to the fetch event.
As a workaround I did something like this to cache my get requests…
function cachedGet (url, config) {
return Promise.race([
getFromCacheAfter4Seconds(url, config),
getFromNetworkAndSaveToCache(url, config)
])
.catch(error => {
console.error('error', error)
return getFromCacheAfter4Seconds(url, config)
})
}
function getFromCacheAfter4Seconds (url, config) {
const cacheKey = url.split('?')[0]
return new Promise((resolve, reject) => {
let timeout = setTimeout(() => {
clearTimeout(timeout)
const cachedResponse = window.localStorage.getItem(cacheKey)
if (cachedResponse) {
const response = JSON.parse(cachedResponse)
console.log('getting from cache', url)
console.log('cachedResponse', response)
resolve(response)
} else {
console.log('no cached response found falling back to network', url)
getFromNetworkAndSaveToCache(url, config)
.then(resolve)
}
}, 4000)
})
}
function getFromNetworkAndSaveToCache (url, config) {
const cacheKey = url.split('?')[0] // For requests that use a startDate & endDate parameters
return axios.get(url, config)
.then(res => res.data)
.then(data => {
window.localStorage.setItem(cacheKey, JSON.stringify(data))
return data
})
}
or to avoid calling the setTimeout anyway whenever Promise.race() is called I did something like this
function cachedGet (url, config) {
return getFromNetworkAndSaveToCache(url, config)
.catch(error => {
if (!error.status) {
// Network error
return getFromCacheAfter4Seconds(url, config)
} else {
throw error
}
})
}
Is there a better/ more recommended way? perhaps a configuration file I can use to specify cache-first vs offline-first vs whichever is faster? Same thing if I were to use other service worker features like background sync and/or push notifications.
Issue Analytics
- State:
- Created 5 years ago
- Comments:7
Top GitHub Comments
@khaledosman You can append an epilog to the auto-generated SW in a build step (without ejecting or forking CRA) and, there, add a message listener which can access SW
self
object. For example, I use this technique to upgrade SW in https://github.com/emibcn/Rac1.js/blob/master/app/src/sw-epilog.js :And then, from your app https://github.com/emibcn/Rac1.js/blob/master/app/src/index.js :
Note: Don’t forget to add the epilog to your build process in your
package.json
. For example https://github.com/emibcn/Rac1.js/blob/master/app/package.json#L27 :This issue has been automatically closed because it has not had any recent activity. If you have a question or comment, please open a new issue.