قالب وردپرس درنا توس
Home / IOS Development / Reag data layer – Part 6: Offline reader

Reag data layer – Part 6: Offline reader



This post is the sixth part of an 8-part series that delves deep into how to build a robust, real-world frontend app data layer. See the previous sections here:

Using the latest browser features to store your code and the data without the net, it can get a better experience for the web app's users, but it comes with a cost. This really makes your app a distributed system, in the sense that it is both local and remote, and they must be kept in sync, and distributed systems are inherently complex. Even in the simplest cases, it will take more work to build the code and more attention to ensure that you do not crush things when making changes.

In this post, we go through some of the offline features you can easily set up using Redux connectivity to a RESTful web service. Then we will discuss alternatives if you have more complex needs.

If you want, you can download the app at the end of the post.

Persistent Redux Data

In Part 3, we started to log in state by installing Redux Persist and storing a logon flag. We went with Redux Persist because we knew we should also store our entire Redux store.

Blast the network connection to Slow 3G and reload the page.

 slow 3G

Note that although we have maintained our data, we do not see any difference in app behavior yet: we still get a loading indicator until the web service request returns. This is because as soon as the logged-in page shows, we turn off a request to load the data from the server, which causes the loading message to appear instead of our data. Although the video games are uploaded from persistent storage, they are not displayed.

Thinking about why this is and how we can improve it, it is useful to think about offline patterns Jake Archibald describes in his Offline Cookbook. We use the terms in a different context, but they are still useful for talking about caching and network data decisions.

(Offline Cookbook talks in the form of HTTP requests sent via a service worker, addressing if the service worker decides to respond to them from the cache or from the network. In our case, as mentioned in part 4, we do not use a service worker for cached data, but instead we use data that is cached in Redux Persist, so for us, the decision between cache and network is the decision to save data that is already cached in the Redux store or to do a network request to retrieve updated data.)

The user's experience right now in the app can be described as "network only". When they load the video game screen, if there is no network connection, they get an error.

What other options do we have?

Networks that fall back to the cache

One option would be to display the cached data if the network request fails. This is referred to as "Networks that fall back to the cache".

All we have to do to implement this is to change how our LoadingIndicator works:

   const LoadingIndicator = ({loading, error, child}) => {
if (loading) {
return 
; -} other if (wrong) { - return

An error occurred.

;
} other { return
+ {possibleErrorMessage} {child}
; } }; + const possibleErrorMessage = (error) => { + if (incorrect) { + return

An error occurred.

; +} +}; +
export standard LoadingIndicator;

After this change, the error status is no longer a different state in our app. If the app has failed, we will only show the error message at the top of the list of records. If we did not have offline data, this would not give us any benefit, because if the request failed, we would probably know that we would not have any data. But now we can have adopted offline data.

Run the app and log in once to make sure the game data is downloaded. Then select the "Offline" checkbox and click the Upload button we created. You should see the shortened card, then the list of video games should reappear, with an error message at the top.

 Networks that fall back to cache

Cache Falling Back to Network

Another alternative we could have Firstly, try to view the cached data and just make a network request if we don't some cached data. This is called "Cache Falling Back to Network."

How can we decide whether we have cached data or not? We can only check that the list of video games is empty, but it can be unreliable. The list will also be empty if we deleted all the video games. It can be more reliable to track a new state property that only registers if we have loaded data before. Add a new loaded reduction machine to games / reducers.js :

  + export function (state = false, action) {
+ switch (action.type) {
+ case STORE_GAMES:
+ back true;
+ standard:
+ return mode;
+}
+}
 ...
export standard combine Reduce ({
game,
 + loaded,
 loading,
error,
});

Notice how easy it is; It starts to fall and we put it right the first time we succeed in loading games and never change it again.

Configure Now GameList / index.js to map it to a plug for ] GameList :

   feature mapStateToProps (state) {
return selection (state.games, [
& # 39; play & # 39 ;,
 + & # 39; loaded & # 39 ;,
 & # 39; loading & # 39 ;,
& # 39; error & # 39 ;,
]);
}

Now, in Playlist check loaded flag before calling loadGames () :

   const GameList = ({
game,
 + loaded,
 loading,
error,
load games,
addGame,
Log out,
}) => {
useEffect (() => {
 - loadGames ();
  + if (! Loaded) {
+ loadGames ();
+}
}, []);

Now, the playlist play screen is first loaded fake and this confirms that we do not have a cache of records. So we fall back to the network and make a loadGames () request. From here, loaded will be true and confirm that we have a cache. Then we do not automatically make the network request. As a result, LoadingIndicator will only show our records right away. Run the app to confirm that this is the case.

Note that in this approach, our app does not automatically receive updates from the server; we need to click Update manually to get them. There is another approach we can take that gives us the best of both worlds in some scenarios.

If we have cached data, we can show it right away, and also a server request. If we receive data in response, we can update the data displayed. This is called "Cache Then Network". This is a good standard approach: Ember Data, the Ember.js built-in data layer, takes this approach for all requests by default.

To do this work from a UX perspective, we will display our cached data while the network request is running to hopefully retrieve the new data. We can implement this by making another change to LoadingIndicator :

   const LoadingIndicator = ({loading, error, child}) => {
 - if (loading) {
- back 
- -
; -} other { - back
- {possibleErrorMessage} - {children} -
; -}
+ return
+ {possibleLoadingMessage (loading)} + {possibleErrorMessage} + {child} +
;
}; + const possibleLoadingMessage = (loading) => { + if (loading) { + return ; +} +};

Please note that we now always display our video game title list; We can only display a load or error message at the top of these states.

In this approach, we no longer need our loaded state object because we always want to make a network request so that we can reset the change we previously made to GameList.js : [19659017] const GameList = ({
game,
– loaded,
loading,
error,
load games,
addGame,
Log out,
}) => {
useEffect (() => {
– if (! Loaded) {
– loadGames ();
-}
+ loadGames ();
}, []);

And Playlist / index.js :

   feature mapStateToProps (state) {
return selection (state.games, [
& # 39; play & # 39 ;,
 - & # 39; loaded & # 39 ;,
 & # 39; loading & # 39 ;,
& # 39; error & # 39 ;,
]);

And games / reducers.js :

  export function loaded (state = false, action) {
- switch (action type) {
- case STORE_GAMES:
- back true;
- default:
- return mode;
-}
-}
 ...
export standard combine Reduce ({
game,
 - loaded,
 loading,
error,
});

Run the app, check the "Offline" checkbox and click "Load". You should see the preprocessor, then the error message, but the cached data should continue to appear all the time.

 cache da network error

Note that in the console you will see a warning from Redux Continue that an unexpected key loading was found in the persistent data and will be ignored. When you change your persistent data, it's important to keep in mind that users of your app already have data permanently in their old format. In this case, the default entry was good, but in more complex cases, you might need to add code to detect data in the old format and transfer it to the new format.

In this post we have covered four major patterns for reading data:

  • Network Only
  • Networks that fall back to cache
  • Cache falls back to the network
  • Cache Then Network

For your application Think about the deviations from these approaches and decide which ones work best. You can take different approaches for different data records. For now, let's stick to the "Cache Then Network" for our video games.

With this we have handled reading data while you are offline. This is great, and for most read applications it may be just what the users need. But is there anything we can do if our users need to write data while they are offline? It is, but it will take some work. We find out how in the next part.




Source link