0

I have a set of components that run inside a custom tab. This does not have an 'Application' root, just rather a component that holds several other components. Everything works great here.

The problem I'm having is when we include implements="lightning:isUrlAddressable" the parent component no longer initializes after we manually destroy the components on an aura:locationChange event. We destroy the component so the events do not keep running when a user navigates back to the component and a new set of events are fired, aka duplicate instances of the component.

Is there any way to cause the component to re-initialize when navigating back to the tab?

EDIT:

After some thinking, my main issue really lies around the aura:locationChange event. Let me explain

<!-- parent component -->
<aura:component>
    <aura:handler event="aura:locationChange" action="{! c.destroyComponent }" />

    <!-- child component1 -->
    <aura:component>
        // does fun stuff
    </aura:component>

    <!-- child component 2 -->
    <aura:component>
        <!-- see explanation below -->
        <aura:handler event="aura:locationChange" action="{!c.saveCartOnNavAway}" />
    </aura:component>

</aura:component>

Explanation: What the desired outcome here is that when a user leaves this tab, I want to save their records as they have them. I want this handled wherever they are within the parent component. I tried to stop propagation of this even within the {!c.saveCartOnNavAway} method, however, and if I'm understanding correctly, it will only stop it form bubbling up further in the component hierarchy. So lets say they are in our parent component tab, and the user navs to the Accounts Tab, the locationChange event will fire, as expected and desired. Now when the user navigates to the Contacts tab, the locationChange event is fired again, as expected behaviour, but it is again handled in my nested component, which is NOT desired, and leaves me with multiple saving of a record that does not need saving. This is where we decided to destroy the component. If we destroy the parent component on aura:locationChange, the record gets saved and the nested component is no longer firing every time the user changes a tab.

So now, we add in the lightning:isUrlAddressable interface. We have a specific instance where the user has the ability to enter our component from a VF page. They will NOT always be coming to our component in this manner, but now have the ability to. So now, the behavior is when the user navigates away from the component tab, we destroy the component as before, but when we navigate back, the component isn't being created again as it was before, which means no init runs, the tab space is blank. Calling the change event on pageReference will also not fire as the component was destroyed.

All this brings me back to:

1) How can I cause the component to be created again, which was mostly answered as in you really can't, and best bet is to not destroy the component.

2) If I don't destroy the component, how do I keep the locationChange event from being handled on every locationChange event anywhere in the application. As adding a stop.Propagation() did not prevent that. I did read the documentation, and I do still struggle on wrapping my head around it.

3) Is there another/better solution to save my cart information when a user navs away from my tab? One that I could maybe add a globalId attribute to know which instance I want my cart saved or not.

The desired result at the end of the day is to be able to save the cart when the user changes their location, as this was the initial reason that we destroyed it in the first place. Adding the isUrlAddressable causing the component to no longer be created again when you nav back to the tab is more or less a side effect that was brought to the surface.

7
  • Rather than destroying the components why not stop the event propagation? Also minimal code here might help get a better idea! Nov 2, 2018 at 2:27
  • I thought about that. We have one that checks for when you nav away (aura:locationChange) that we save the current state of the record. If I stop that propagation of the event, will it no longer fire when they nav back to the tab, make updates and leave again?
    – JRiffe
    Nov 2, 2018 at 3:24
  • Look at event.stopPropagation(). It really very confusing to say anything without getting a good dive into overall implementation. But once you stop the event they won't propagate from that point further! Nov 2, 2018 at 3:50
  • I updated my question with a bit more details. When I tested, even after stopping propagation, the location change was still fired and handled.
    – JRiffe
    Nov 2, 2018 at 14:47
  • Just a quick update the stop.Propagation() wont stop system event which is what change handlers are! Let me take sometime to respond. May be one way to save the info would be using browser localstorage Nov 2, 2018 at 14:54

2 Answers 2

1

1) How can I cause the component to be created again, which was mostly answered as in you really can't, and best bet is to not destroy the component.

Usually one should avoid the need to destroy the components. But if you do have to, it's better to let salesforce to take over that job for you. In your case what i mean is instead of you manually destroying the components wrap your child components with aura:if and toggle around with the conditions the idea of using aura:if is because it creates and destroys DOM on the fly based on the condition rather than hiding it.

2) If I don't destroy the component, how do I keep the locationChange event from being handled on every locationChange event anywhere in the application. As adding a stop.Propagation() did not prevent that. I did read the documentation, and I do still struggle on wrapping my head around it.

The tricky situation here is stopPropagation would have been ideal if your'e talking about custom events fired by you, here its a system event we're talking about so you had issues stopping it from propagating any further

3) Is there another/better solution to save my cart information when a user navs away from my tab? One that I could maybe add a globalId attribute to know which instance I want my cart saved or not.

Usually to save state around the client side javascript local storage is a good option

Note: When things do get really messy it's better to take a step back an rethink the approach.

3

Lightning navigation does not refresh the state of components, how to fix a bug

In the component with lightning:isUrlAddressable simply add a change handler for the pageReference state.

<aura:handler name="change" value="{!v.pageReference}" action="{!c.reInit}" />

And then your reInit method can reset the component back to whatever it needs to be.

4
  • This is interesting. I'll give this a shot and let you know.
    – JRiffe
    Nov 2, 2018 at 3:26
  • I did try this. And with the component being destroyed, it won't fire the change event. If I don't destroy the component, I'm back with the original issue of multiple events.
    – JRiffe
    Nov 2, 2018 at 3:38
  • What about leaving the host component (the one that implements the interface) active, but either 1) destroy just the sub components (if necessary you may need to wrap in one more component layer), or 2) just deactivate the handlers you're worried about. Then on reInit, reactivate.
    – Charles T
    Nov 2, 2018 at 12:13
  • I may have to end up destroying the one component that I have the issue with, and recreated it on the reInit from PageReference change event. At this point just looking for different avenues to keep things working.
    – JRiffe
    Nov 2, 2018 at 14:48

You must log in to answer this question.

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