Angular Offline First Application
Develop an Angular application that provides a seamless user experience even when offline. This challenge focuses on implementing mechanisms for data caching and synchronization to ensure the application remains functional and data is updated when connectivity is restored.
Problem Description
Your task is to build a basic Angular application that can store and retrieve data from a local source (like IndexedDB) when the user is offline. When the application detects an online connection, it should synchronize the local data with a remote API.
Key Requirements:
- Offline Data Access: Users should be able to view existing data and perform basic operations (e.g., adding new items, marking items as complete) while the application is offline.
- Data Caching: Implement a mechanism to cache fetched data locally. IndexedDB is the recommended technology for this.
- Synchronization: When the application comes back online, it must synchronize any changes made offline with a remote API. This includes uploading new/modified data and downloading any updates from the server.
- Status Indication: Visually indicate to the user whether they are online or offline.
- Service Worker Integration: Utilize a service worker for robust offline capabilities, including caching of application assets and intercepting network requests.
Expected Behavior:
- When online, the application fetches data from a simulated remote API and displays it.
- When the connection is lost, the application seamlessly continues to function using the locally cached data.
- Operations performed offline (e.g., adding a new item) are stored locally.
- Upon reconnecting to the internet, the offline changes are automatically sent to the remote API, and any new data from the API is fetched and displayed.
- The user should see a clear indication of their current connection status.
Edge Cases to Consider:
- Network Intermittency: How does the application handle rapid switching between online and offline states?
- Data Conflicts: While full conflict resolution is advanced, consider a basic strategy if the same data is modified both online and offline before synchronization. For this challenge, a simple "last write wins" based on timestamp might suffice, or prioritizing online changes.
- Large Data Sets: How would your caching strategy perform with a significant amount of data?
- Initial Load Offline: What happens if the application is accessed for the first time when the user is already offline?
Examples
Example 1: Viewing Data Offline
Input: User accesses the application when their device is offline.
Output: The application displays a list of items that were previously fetched and cached. The UI shows an "Offline" indicator.
Explanation: The application bypasses the network request and retrieves data from its local cache (e.g., IndexedDB).
Example 2: Adding an Item Offline and Syncing Online
Input:
1. User adds a new item ("Buy Milk") while offline. The item is displayed locally.
2. User reconnects to the internet.
Output:
1. The "Buy Milk" item is successfully added to the remote API.
2. Any new items added to the API while the user was offline are fetched and displayed in the application.
3. The "Offline" indicator disappears, replaced by an "Online" indicator.
Explanation: The offline change is queued and sent to the API upon reconnection. The application then fetches the latest data from the API.
Example 3: Application Assets Caching
Input: User navigates to a page that requires specific JavaScript and CSS files.
Output: The application assets (HTML, CSS, JS) are loaded quickly, even if the network is slow or unavailable, due to service worker caching.
Explanation: The service worker intercepts the requests for application assets and serves them from its cache.
Constraints
- The application should be built using Angular 16+ and TypeScript.
- Use
@angular/pwafor service worker setup. - IndexedDB (or a library that abstracts it, like
ng-indexed-dborngx-indexed-db) must be used for local data storage. - A simulated remote API will be provided (or you can mock one using
HttpClientand storing data in memory for demonstration). This API will have endpoints for fetching, creating, and updating data. - The focus is on data synchronization, not complex real-time updates.
Notes
- Consider using a state management pattern (like NgRx, Akita, or a simple service-based approach) to manage application state and connectivity status.
- Think about how to queue up offline actions. A simple array or queue in a service can store pending operations.
- For synchronization, you'll need to compare local changes with remote data. A common approach is to store a flag on each item indicating its status (e.g.,
isNew,isModified,isDeleted) and its last sync timestamp. - The
navigator.onLineproperty can be a starting point for checking online status, but it's not always reliable. A more robust check involves attempting network requests. - Familiarize yourself with the
@angular/pwadocumentation for service worker configuration and lifecycle management.