Handling Offline and Online Scenarios on Same Screen

Hi,

I have a requirement to develop an application that supports offline mode and when network is available the data should be fetched only from server entities not local entities.

With this requirement for any screen dealing with data, it becomes a challenge to restrict data fetch or save operations to either local or server entities based on the network status. For instance, I have a data action to fetch data from server entity and another to fetch data from local entity. Both the data actions are going to run irrespective of the network status and cause overhead to application.

What are my options to fulfill this kind of requirement? Shall I maintain separate screens for each mode?

Thanks,

Junaid

Hi Junaid,

It seems like you've already separated and encapsulated your logic in order to isolate both cases of data fetching. I'm not sure I follow when you say that both data actions will run regardless of network status, what do you mean? Why not validate the network status at every screen and then decide on the method of data fetching with the GetNetworkStatus() action, ensuring only one action will be executed?

Afonso Carvalho wrote:

Hi Junaid,

It seems like you've already separated and encapsulated your logic in order to isolate both cases of data fetching. I'm not sure I follow when you say that both data actions will run regardless of network status, what do you mean? Why not validate the network status at every screen and then decide on the method of data fetching with the GetNetworkStatus() action, ensuring only one action will be executed?

Here is what I mean, lets say I have a server entity ServA and local entity LocA, and I have to show count of records from either of the entities based on network status. For that purpose, using "Fetch Data From Database" option I create an action to fetch from server entity ServA and create another using "Fetch Data From Local Storage" to fetch from LocA. Where would I get the network status to run one of these data actions?


You could use the Fetch Data from Other Sources option:

This would allow you to write more specific logic that could validate the network status before choosing the correct way to obtain your screen data.

Hello Junaid

I don't think what you want to do is easy.

First thing, you will need a local list, so you can have your interface working without worrying if the data will come from local storage or server database.

What you need to do now is to decide if you will fill this local list with data from the local storage or the server database.

There are two ways to fetch data from local storage: 

  1. "Fetch Data from Local Storage" option.
  2. Using an Aggregate in a Client Action.

The first option will always run. The second will have to be triggered somewhere when the page is being built. 

For the server data, you have another problem. no matter if you use "Fetch Data from other sources" or an "Aggregate", when offline both will cause an exception. 

When online, you can use the On After Fetch event of the aggregate to copy the data from it to the local list.
So, now, it is necessary to find a way to identify that you are offline or that you went offline and fill the local list with the local data.

This is the tricky part. 

First, I think you could add an Exception Handler to the Main Flow to catch the network error when executing the Aggregate, so the user does not see the error.

Second, you could have an IF on the page, that would display a web block based on the Aggregate's Has Fetch Error. The web block would just trigger an event when being built, that would be caught by a handler in the page, would execute an aggregate in the local storage and copy the data to the Local List.

I know, a little complex, but I can't see any other way, at the moment, to implement what you are being requested...

Cheers.

Eduardo Jauch wrote:

Hello Junaid

I don't think what you want to do is easy.

First thing, you will need a local list, so you can have your interface working without worrying if the data will come from local storage or server database.

What you need to do now is to decide if you will fill this local list with data from the local storage or the server database.

There are two ways to fetch data from local storage: 

  1. "Fetch Data from Local Storage" option.
  2. Using an Aggregate in a Client Action.

The first option will always run. The second will have to be triggered somewhere when the page is being built. 

For the server data, you have another problem. no matter if you use "Fetch Data from other sources" or an "Aggregate", when offline both will cause an exception. 

When online, you can use the On After Fetch event of the aggregate to copy the data from it to the local list.
So, now, it is necessary to find a way to identify that you are offline or that you went offline and fill the local list with the local data.

This is the tricky part. 

First, I think you could add an Exception Handler to the Main Flow to catch the network error when executing the Aggregate, so the user does not see the error.

Second, you could have an IF on the page, that would display a web block based on the Aggregate's Has Fetch Error. The web block would just trigger an event when being built, that would be caught by a handler in the page, would execute an aggregate in the local storage and copy the data to the Local List.

I know, a little complex, but I can't see any other way, at the moment, to implement what you are being requested...

Cheers.

Thanks Eduardo for detailed response. Regarding network status change while user is on some screen I plan to handle this using network status changed detector. Anytime the network status change is detected I can redirect user to some default screen.

For server data I think a flag can be set in oninitialize and use that to fetch or not the data from server entity. I have not tried it though but I hope it works. 

My screens require data be loaded initially, but in my situation I can only fetch local entities data in client actions, otherwise if I use data actions they would run unnecessary even when network is available. Getting data in client actions would not meet my requirements. And it is not recommended to do heavy data loading in oninitialize, onrender, or onready events. 

Please share your thoughts. 


Well... 

You probably cod use a block that receives the list, and use two different pages, one for local and one for server data. This way you just set the right aggregates at the page and pass the data to the block. A single interface, different pages and data fetching. 

To use a single page, or you live with local data being always fetch, even if online, or you live with data being fetch on a client Action. 

Of course, you probably can do lazy load to the  local storage with some effort, not impacting the page loading, but this would be probably an adventure and decrease maintainability...