Newer Version Available

This content describes an older version of this product. View Latest

Storable Actions

A server-side controller action can have its response stored in the client-side cache by the framework. This can be useful if you want your app to be functional for devices that temporarily don’t have a network connection.

A storable action might result in no call to the server. An action that updates or deletes data should never be marked storable.

Warning

Successful actions, for which getState() in the JavaScript callback returns SUCCESS, are stored.

If a storable action is aborted after it’s been sent but not yet returned from the server, its return value is still added to storage but the action callback is not called.

The action response of a storable action is saved in an internal framework-provided storage named actions. This stored response is returned on subsequent calls to the same server-side action instead of the response from the server-side controller, as long as the stored response hasn't expired.

If the stored response has reached its expiration time, a new response is retrieved from the server-side controller and is stored in the actions storage for subsequent calls.

Marking Storable Actions

To mark a server-side action as storable, call setStorable() on the action in JavaScript code, as follows.

1swfobject.registerObject("clippy.codeblock-0", "9");a.setStorable();

Storable actions are always implicitly marked as abortable too.

Note

The setStorable function takes an optional parameter, which is a configuration map of key/value pairs representing the storage options and values to set. You can only set the following properties:

ignoreExisting
Set to true to refresh the stored item with a newly retrieved value, regardless of whether the item has expired or not. The default value is false.
refresh
Overrides the item's default autorefresh interval. Set the value in seconds. See Refreshing an Action Response for Every Request.
errorHandler
Handles errors thrown during storage. See Error Handling.
executeCallbackIfUpdated
Set to false to suppress the second invocation of the action callback caused when an action is refreshed and its response changes. The default value is true.

To set the storage options for the action response, pass this configuration map into setStorable.

Refreshing an Action Response for Every Request

If a storable action returns dynamic content from the server, set the refresh interval to 0 to ensure that the data is refreshed from the server. If an action response is already cached, the cached response is displayed while the server roundtrip is happening.

To refresh the action response for each request, set:

1swfobject.registerObject("clippy.codeblock-1", "9");a.setStorable({
2    "refresh": 0
3});

Examples

This example marks an action as storable, forces a refresh next time the action is called, and overrides the autorefresh interval to 10 seconds.

1swfobject.registerObject("clippy.codeblock-2", "9");a.setStorable({
2    "ignoreExisting": true,
3    "refresh": 10
4});

This next example shows how to use setStorable() to store the server-side action response in a client-side cache. The markup includes a button that triggers the runActionAtServerAndStore client-side controller action. This client-side action calls a fetchDataRecord server-side action. Next, the action is marked as storable and is run. The server-side action return value is obtained in the callback.

This is the component markup that initializes the actions storage and contains a button.

1swfobject.registerObject("clippy.codeblock-3", "9");<aura:component render="client" extensible="true" 
2 controller="java://org.auraframework.impl.java.controller.AuraStorageTestController" 
3 implements="auraStorage:refreshObserver">
4            
5    <auraStorage:init debugLoggingEnabled="true"
6                         name="actions" 
7                         secure="true" 
8                         persistent="false"
9                         clearStorageOnInit="true"
10                         defaultExpiration="50" 
11                         defaultAutoRefreshInterval="60" />
12
13    <ui:button label="Run action at Server and mark as storable"
14      press="{!c.runActionAtServerAndStore}" 
15      aura:id="ForceActionAtServer"/>
16
17</aura:component>

This is the action in the component’s JavaScript client-side controller.

1swfobject.registerObject("clippy.codeblock-4", "9");runActionAtServerAndStore:function(cmp, evt, helper){
2    // Get server-side action 
3    var a = cmp.get("c.fetchDataRecord");
4
5    // Set server-side action as storable
6    a.setStorable();
7
8    a.setCallback(cmp, function(a){
9        var returnValue = a.getReturnValue();
10    });
11
12    // Run server-side action
13    $A.enqueueAction(a);
14},

You can also check whether an action response originates from storage by calling isFromStorage on the action object in the callback function of the JavaScript controller.

Error Handling

Specify a handler when an error occurs during configuration of a storable action. This example shows component markup that initializes the actions storage with a maximum size of 10 KB.

1swfobject.registerObject("clippy.codeblock-5", "9");<aura:application controller="java://org.auraframework.JavaTestController">
2    <auraStorage:init name="actions" maxSize="10"/>
3</aura:application>
4

This is a client-side test that ensures the error handler is invoked when the error is thrown during storage. In this example, the array tooLarge results in a value larger than the maxSize value of 10 Kb. This condition triggers an error message in the getItem() method of the memory storage adapter. $A.test.addWaitForWithFailureMessage compares the expected error message with the actual, returning a callback when the comparison returns true. The callback function in this example checks that the action should not be found in storage, since an error is thrown during storage.

1swfobject.registerObject("clippy.codeblock-6", "9");test : function(component) {
2    var errorHandled = null;
3    var action = component.get("c.getString");
4    var tooLarge = new Array(15000).join("!");
5    action.setParams({ param: tooLarge });
6    
7    action.setStorable({
8        errorHandler: function(error) {
9            errorHandled = error;
10         }
11     });
12     $A.run(function() {
13         $A.enqueueAction(action);
14     });
15     $A.test.addWaitForWithFailureMessage(
16         "MemoryStorageAdapter.setItem() cannot store an item over the maxSize", 
17         function() {  return errorHandled; },
18         "expecting error message from memory adapter",
19         function() {  
20         $A.clientService.isActionInStorage(this._actionDescriptor, action.getParams(), 
21          function(isInStorage) {
22              $A.test.assertFalse(isInStorage, 
23                  "Action with error should not be found in storage.");
24          }
25  );
26         }
27    );
28