10

There is a Lightning community consisting of 2 pages:

  1. Search page: There are few fields and a search button. Upon entering the fields, the list of accounts are displayed.
  2. Detail page: If user clicks on any one of the account in the search page, it will take you to its detail page.

We have this scenario where the user can click Back button of the browser on the detail page. But the issue is that the fields which the user had entered are blank, and the search page doesn't display the last search results

1 Answer 1

13

Lightning behaves differently due to its JavaScript-based design. If you want to preserve some data, you have to store it somewhere and get it back later. One way that I've found to do this is to provide session-backed storage. This allows the component to retain data in the browser's session storage area, which is typically wiped out when the user closes their browser.

Here's a basic implementation:


Component code

<aura:handler name="init" value="{!this}" action="{!c.init}" />

<lightning:input name="searchText" type="text" value="{!s.searchText}" label="Search Term" />

<lightning:button type="search" label="Search" onclick="{!c.search}" />

Controller Code

({
    init: function(component, event, helper) {
        helper.setup(component);
        if(component.get("s.searchText")) {
            helper.search(component);
        }
    },
    search: function(component, event, helper) {
        helper.search(component);
    }
})

Helper Code

({
    setup: function(component) {
        component.addValueProvider(
            's',
            {
                get: function(key, comp) { return sessionStorage.getItem(key); },
                set: function(key, value, comp) { sessionStorage.setItem(key, value); }
            }
        );
    },
    search: function(component) {
        // implementation not given //
    }
})

The magic here is that when the component or application is reloaded, it will remember the previous term, if any, and automatically execute a search. Note that this means that the list may be different if the values changed from the last refresh, but this is probably acceptable.

Alternatively, you can set up a hash value provider. This puts the search term in the URL, allowing back/forward to work normally. Here's what that implementation looks like:


Component (No Changes)

Controller (No Changes)

Helper

({
    setup: function(component) {
        component.addValueProvider(
            's',
            {
                get: (key, comp) => this.parseHash()[key] || "",
                set: (key, value, comp) => { this.storeHash(key, value); }
            }
        );
    },
    storeHash: function(key, value) {
        var result = [], temp = this.parseHash();
        Object.keys(temp).forEach((v) => result[v] = encodeURIComponent(result[v]));
        temp[key] = encodeURIComponent(value);
        Object.keys(temp).forEach((v) => result.push(key+'='+temp[key]));
        location.replace("#"+result.join('&'));
    },
    parseHash: function() {
        var results = [],
            parts = location.hash? location.hash.replace(/^#/,'').split(/&/): [];
        parts.forEach((v) => results[v.split(/=/)[0]] = decodeURIComponent(v.split(/=/)[1]));
        return results;
    },
    search: function(component) {
        // not implemented //
    }
})

This implementation has the advantage of also being bookmarkable, in case the user would like to return to the search. You can use the value provider to store all kinds of useful stuff in the hash. For example, if you have pagination, sorting, etc, you can put all those variables there.

If you want some obfuscation, though, you could also encode the parameters differently. I simply used a URL-looking syntax for convenience, but you could store encoded JSON data or whatever else makes sense for you if you'd like.

2
  • Interesting, is this use of addValueProvider formally documented anywhere and/or recommended by SFDC?
    – Charles T
    Commented Jan 7, 2018 at 17:18
  • @CharlesT It's in the Aura Documentation (login.salesforce.com/auradocs/reference.app). The only reference to it in the Lightning Components Developer Guide state that it is an allowed function under Locker Service. As far as I can tell, these two examples are the only working examples on the Internet (aside from the other answer I wrote). Since Locker Service explicitly allows it, that means we're allowed to use it.
    – sfdcfox
    Commented Jan 7, 2018 at 19:13

Not the answer you're looking for? Browse other questions tagged .