Refreshing Accounts
For efficiency, HQ and UUX cache a user’s accounts for the duration of a session. This means from the moment your end user logs in until they log out, their account list will not change. Most of the time, this leads to a snappier front end experience, since calculating accounts is an expensive operation, often involving real time calls to the Core. However, if your workflow involves updating or linking an account, this is a hindrance. Fortunately, the SDK provides a way of refreshing these accounts outside of the normal login flow.
Warning
This only applies to workflows where the end user logs into the Online environment
The accounts are cached in both UUX and HQ. So you need to clear the cache in HQ and UUX for account changes to show up. Let’s first cover the HQ cache clearing using HqCommands.
Backend Process
- class q2_sdk.hq.models.hq_commands.HqCommands(reload_type, accounts_to_reload, force_success_response=False, disclaimer_id_to_skip=None)[source]
For use with sending special instructions to HQ via an execute_request_as_xml response
- Parameters:
reload_type (
AccountReloadType) – Reload from either Q2’s database or the Host Adapteraccounts_to_reload (
list) – List of account numbers (host account ids HAIDs). If blank, will reload ALL accounts (This can be expensive and is not recommended)force_success_response – Must be set to True to allow Disclaimers to move on with their flow
disclaimer_id_to_skip (
Optional[int]) – Q2_DisclaimerFormData.DisclaimerFormDataID. If set, will mark the disclaimer viewed for the duration of the online session
To understand the use of this method, let’s review a typical SDK workflow:
Q2Online -> HQ -> SDK -> HQ -> Q2Online
The end user does something in the online environment. Perhaps clicking on a submit button in your SDK form.
This tells HQ to find the registered SDK extension. HQ then POSTs to your extension with a blob of XML including the user’s information, such as their email, SSN, Account List, etc.
It is the responsibility of your extension to generate some HTML to return back to HQ, which the SDK framework wraps in an appropriate SOAP response before returning.
Step 3 returns something like this:
<FormRsp xmlns="http://tempuri.org/FormRsp.xsd">
<FormResp>
<TargetUrl/>
<PrependVirtualDirToUrl>false</PrependVirtualDirToUrl>
<MessageToEndUser/>
<NewFormData>{form_data}</NewFormData>
<NewFormShortName/>
{hq_commands_xml}
</FormResp>
</FormRsp>
{form_data} is substituted with whatever you return from your extension. Meanwhile, {hq_commands_xml} can give HQ special instructions. This is the hook that allows us to refresh the accounts during an active session.
In practice it looks something like this:
from q2_sdk.hq.models.hq_commands import HqCommands
...
async def submit(self):
...
html = self.generate_html() # Imagine this does some magic to generate your form
accounts_to_refresh = []
for acct in self.account_list:
accounts_to_refresh.append(acct.host_acct_id)
self.set_hq_commands(
HqCommands(
HqCommands.AccountReloadType.FROM_HOST, # Host means Core in this case
accounts_to_refresh
)
)
return html
You are returning your HTML as you normally would, but calling self.set_hq_commands will inject an appropriately formatted {hq_commands_xml} string into Step 3 above.
Note
You cannot utilize the refreshed accounts in the same call in which self.hq_commands is set. The accounts are not refreshed until the method is returned. A common mistake is try to act on the refreshed account list during the same call in which self.hq_commands is set. Until that call is returned, HQ has not been given the instruction to refresh the accounts from the core.
HQ Timing Constraint
HQ processes HqCommands asynchronously — the account reload from the Core does not happen instantly. By the time your frontend code receives the response and proceeds to clear the frontend cache, HQ may still be in the process of reloading accounts. If the frontend re-fetches account data before HQ has finished, the response will still contain stale data.
This is a known timing constraint. In practice, it means that account balances may not update on the first attempt and may require a short delay or a subsequent refresh to reflect the latest data. Consider adding a brief delay before clearing the frontend cache to give HQ additional time to complete the reload.
Caliper API Limitation
set_hq_commands() is only available on handlers that extend Q2HqRequestHandler (or its
subclasses like Q2TectonClientRequestHandler and Q2TectonServerRequestHandler). Handlers
that extend Q2BaseRequestHandler directly, such as the Caliper API handler, do not have
access to set_hq_commands() and cannot trigger an account refresh.
If your workflow involves the Caliper API and needs accounts refreshed afterward, you will need
to make a separate call from your frontend to an HQ-facing extension route that triggers the
HqCommands. For example, your extension could have a dedicated refresh_accounts route that
only sets HqCommands, which can be called via requestExtensionData from the frontend after the
Caliper API workflow completes.
Frontend Process
After initiating the HqCommand on the backend to refresh accounts in HQ, you need to clear the
frontend cache in UUX so that fresh data is fetched on the next request. There are two Tecton
capabilities available for this: clearCache and notifyRefetchAccounts.
clearCache
clearCache clears the frontend HTTP data cache for entries matching a given prefix. When used with the account cache prefix, it also notifies the platform that account data needs to be refreshed.
tecton.actions.clearCache('mobilews/accounts');
The correct cache key for refreshing account balance data is mobilews/accounts. Other cache keys
are valid for their own purposes (e.g., clearing account group data) but will not trigger an account
refresh.
Extensions can listen for cache clear events using tecton.sources.cacheCleared:
tecton.sources.cacheCleared('mobilews/accounts', function() {
// React to accounts being cleared from the cache
});
notifyRefetchAccounts
notifyRefetchAccounts is specifically designed for account refresh scenarios. In addition to clearing the account data from the frontend cache, it also clears the transfer cache.
tecton.actions.notifyRefetchAccounts();
Note
notifyRefetchAccounts does not trigger tecton.sources.cacheCleared events.
If your extensions need to respond to cache clear notifications, use
tecton.sources.refetchRequired instead:
tecton.sources.refetchRequired('mobilews/accounts', function() {
// React to account data being invalidated
});
Which to Use
Both capabilities clear the frontend account cache and notify the platform that account data should be re-fetched. The key differences are:
Use
clearCache('mobilews/accounts')when your extensions need to receivecacheClearedevents, or when you need to clear cache entries for a custom prefix beyond account data.Use
notifyRefetchAccounts()when your workflow involves transfers and you need the transfer cache cleared as well.Both can be called together if you need the benefits of each.
Both capabilities also notify extensions listening via tecton.sources.refetchRequired.
Dashboard Behavior
When either clearCache('mobilews/accounts') or notifyRefetchAccounts() is called while
the user is on the landing page, the account list will update in-place without requiring a
page navigation. However, this is subject to the HQ timing constraint described above — if HQ
has not finished reloading accounts from the Core, the in-place update will display stale data.
Navigating away from and back to the landing page also triggers a fresh data fetch, but is equally subject to this timing constraint.
Examples
Here’s an example of a possible workflow that can be applied to both Server Side Rendered (SSR) and Client Side Rendered (CSR) extensions:
function clickHandler(event) {
tecton.connected.then(() => {
// First, call a route in your extension that triggers the HqCommand to refresh accounts
tecton.sources.requestExtensionData(
{
route: 'submit'
}
).then((xhr) => {
// Once the backend responds, clear the frontend cache
tecton.actions.notifyRefetchAccounts();
});
});
}
const myButton = document.getElementById("my-button");
myButton.addEventListener("click", clickHandler);
Another example could be to add a script tag to the HTML template being returned:
<script>
tecton.connected.then(() => {
tecton.actions.notifyRefetchAccounts();
});
</script>
UUX Payload Script Pattern
Account refresh can also be triggered from a UUX Payload Script. A common use case is refreshing
accounts after an SSO overpanel closes (e.g., after a third-party transfer). The payload script
listens for the OVERPANEL_CLOSED event, calls the backend to trigger the HqCommand, and then
clears the frontend cache.
For a full code example of this pattern, including cache invalidation and platform event filtering, see the Cache Invalidation section of the UUX JavaScript Payload guide.