Similar to the HttpClient, but more specific. While the HttpClient is responsible for managing every request (views, json data, images, etc), the ViewClient is only responsible for fetching views, i.e. server driven pages. The ViewClient creates the BeagleRequest that is sent to the HttpClient. The default implementation does two things:
preFetch
is true
and, asynchronously, pre-fetches their results.It does nothing other than this, and this might be enough for most applications. But some applications may need extra behavior when fetching views, and this is the place where it should be implemented.
A good example is caching. Let’s say we want to locally store a view so when Beagle calls viewClient.fetch
again, it returns the cached result instead of calling the hHttpClient. To do this, we can implement a new ViewClient that has storage and implements fetch
as follows:
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
class MyViewClient extends DefaultViewClient {
MyViewClient({required HttpClient httpClient, required BeagleLogger logger, required UrlBuilder urlBuilder})
: super(httpClient: httpClient, logger: logger, urlBuilder: urlBuilder);
static final key = 'view_client_cache';
SharedPreferences? prefs;
@override
Future<BeagleUIElement> fetch(RemoteView route) async {
prefs ??= await SharedPreferences.getInstance();
final routeKey = '$key:${route.url}';
if (prefs.containsKey(routeKey)) {
final jsonString = prefs.getString(routeKey);
final map = json.decode(jsonString);
return BeagleUIElement(map);
}
final result = await super.fetch(route);
prefs.setString(routeKey, result.toString());
return result;
}
}
Above we implemented a very simple logic that will store every fetch result into the disk using the lib sharedPreferences
. This was done exclusively for demonstration, because this cache would never expire, but the objective here is just to show how such feature could be implemented using the ViewClient.
We extended the DefaultViewClient to take advantage of everything that is already implemented there, like the pre-fetch behavior. But you can also write it from the ground up by extending ViewClient
, which is just an interface.
After creating your custom ViewClient, you just need to pass it to your BeagleService instance:
final baseUrl = 'https://my-bff.com';
final httpClient = const DefaultHttpClient();
final logger = const DefaultLogger();
final urlBuilder = UrlBuilder(baseUrl);
final viewClient = MyViewClient(httpClient, logger, urlBuilder);
final beagleService = BeagleService(
baseUrl: baseUrl,
httpClient: httpClient,
logger: logger,
urlBuilder: urlBuilder,
viewClient: viewClient,
// ...
);
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.