SFDC Stop - Always the latest about Salesforce


Full Tutorial Series with videos, free apps, live sessions, salesforce consulting and much more.


Telegram logo   Join our Telegram Channel

Sunday, 8 April 2018

Salesforce Lightning Events Part 3 - Bubble and Capture Phase

This blog is in continuation to my previous blog post, so if you haven't read the previous blog at least have a look at the code here as I am not going to embed all the code snippets again in this blog.

As we already know about what component events are and we have also made a small application using component events in previous post. It's time to modify that application a little and learn more about types of phases in component events. You must have read earlier about Bubble and Capture phase in component events in my blog post Salesforce Lightning Events Part 1 - Component Events Introduction. We are going to see these phases in action here.

So, If you remember the code used in my previous blog, I have made a simple component event which will run by default in bubble phase to calculate the total income from the entries present in lightning datatable and pass that total income to the parent component from the source component using an event by clicking on Calculate Total Income Button. When you click on this button, you see the output like this:-

Output 1 - Alert message from source component that fired the event

This simply means that, as the lightning event traverse in bubble phase by default, therefore the handler of source component that fired the event is executed first and so we get the alert message - Event handler at source component that fired the event. Moving on to the second output which looks like below:-

Output 2 - Alert message from parent component

This is the event handler defined at the parent component which is executed when the handler at the source component is already executed. As in the bubble phase, the handler at the source component is executed first and then the event is traversed up in the hierarchy and the handler at the parent component is executed.
({
    // Function to handle Lightning Event
    handleTotalIncomeComponentEvent : function(component, event, helper) {
    	alert('Event handler at the parent component');
    	// Getting the value of totalIncome attribute of event using event.getParam()
    	var totalIncome = event.getParam('totalIncome');
    	// Setting the totalIncome attribute of component with the event's totalIncome attribute value.
    	component.set('v.totalIncome', totalIncome);
    }
})
If you remember, the handler defined at parent component as shown above, after the alert message, we set the value of totalIncome argument. So, we have a final output like this:-

Output 3 - Final change in the totalIncome variable by the parent component handler

Understanding Bubble Phase in Component Event

Now, let's make a small change in event handler in our source component i.e. in file LightningEventsComp1Controller.js, right now you have the following code:-

I am going to add one more line in this code and that is event.stopPropagation(); So, my final code is like given below:-

Now when  you run this app, you'll see that only output 1 is there and output 2 and 3 didn't came. So, what's the reason behind that ? You guessed it right..!! By default the event is propagating in Bubble Phase therefore, when we added event.stopPropagation(); in the handler defined in source component, the event stopped propagating and it didn't reached the parent component and so we didn't got output 2 and 3. We got only Output 1 in this case.

Okay, so we got the fact that how the events propagate in the bubble phase. Now it's time to move on to the capture phase. Remove the event.stopPropagation(); line so that we are back in the previous state where we were getting all the outputs 1, 2 and 3.

Understanding Capture Phase in Component Event

In our code, firstly move to LightningEventsComp1.cmp file and checkout the handler for event. You'll see something like this:-


Now, in the above code, I am going to add one extra attribute in the handler i.e. the final code is like given below:-

Notice that, I have added another attribute as phase="capture" in the event handler specifying that this event handler will now handle the capture phase of the fired event. Similarly, make this change in the handler present in LightningEventsCompContainer.cmp file. The initial and final versions of the second file are given below:-

Initial Version


Final Version

Now, as you can see in the final version of both the files, the handlers have added the attribute phase="capture". Now let's click on Calculate Total Income button again and check the changes in outputs. You'll see that the order of the output is Output 2 -> Output 1 -> Output 3. Now, we know that in capture phase the event start propagating from the application root. Therefore, the Output 2 i.e. alert in parent component appear before the alert in source component.

Notice that even the source component is firing the event and it has a handler defined to handle that event still the handler of parent component handles the event first because as the event is fired, it directly go to the application root without the handler being executed at the source component (if any) and then traverse down to the source component that fired the event.

There is a matter of surprise that the Output3 i.e. the updating the total income value should have occurred after output 2 and then output 1 should occur. Yes, you are right and this is only how it's happening but the point is that as the js updated the value of total income it didn't stop executing and the next alert message came up before the effect of change in totalIncome is reflected. The parent component handler is executed before the source component.

To make sure this concept you can add event.stopPropagation(); to the parent component handler function as given below:-

LightningEventsCompContainerController.js - Before adding stop propagation method

LightningEventsCompContainerController.js - After adding stop propagation method


You'll see that the child component handler is not executed as the event stopped propagating after reaching the parent component.So, the order of the output is as follows:- Output 2 -> Output 3.

So, we have seen the bubble phase as well as the capture phase and also the path the event follow in both the phases. But wait, these phases are only associated with event handler right..!!

What will happen when I configure one handler to handle bubble phase and other to handle capture phase ?? Let's figure it out.

Remove the event.stopPropagation(); so that we can continue again from the initial stateAs the event run in both the phases, you'll see no change as both the handlers will run when you run one handler in bubble and other in capture phase. But, notice that the handler which is in capture phase run first and the handler which is in bubble phase run after that.

Suppose you only add phase="capture" to LightningEventsComp1.cmp and the LightningEventsCompContainer.cmp runs in bubble phase as default. Given below is the handler in both the files:-

LightningEventsComp1.cmp


LightningEventsCompContainer.cmp

Now, you'll see that the order of output is as follows:- Output 1-> Output 2-> Output 3. So, the source component handler runs in capture phase and is executed first whereas the parent component runs in bubble phase and is executed after that. Before discussing why this happened let's make one more change which is just reverse of this. Let's add phase="capture" to LightningEventsCompContainer.cmp this time and not to LightningEventsComp1.cmp as shown below:-

LightningEventsComp1.cmp


LightningEventsCompContainer.cmp

Now, when you run the app again, you'll see that the order of output is as follows:- Output 2-> Output 1-> Output 3. Make sure that you don't get confused by Output 3 as it's the js delay in changing the value due to which other alert is executed as explained by me earlier. Just focus on Output 1 and Output 2. So, we got to know that this time the handler in LightningEventsCompContainer.cmp was in capture phase and executed first whereas handler in LightningEventsComp1.cmp was in bubble phase and executed later.

So, from this, we can conclude that,

"If handlers of same event are in different phases, then the handlers in capture phase are executed first following their order where as the handlers in bubble phase are executed in their order after the handlers in capture phase have done their execution".

In other words we can say that the capture phase is always handled before the bubble phase. But as we see, both the handlers are executed both the time. So, to have a better understanding, let's consider the previous code in which we have LightningEventsCompContainer in capture phase and LightningEventsComp1 in bubble phase. We are only going to do a single change now i.e. we are going to add event.stopPropagation(); to our handler action which is running in capture phase. So, below is the LightningEventsCompContainerController.js :-

As you can see above, we have added event.stopPropagation(); at the last line. Therefore, when you run the app now, you'll get the output in the following order:- Output 2 -> Output 3. Notice that Output 1 is not there. This is because, the capture phase stopped the event propagation and the event is not propagated in any phase after that. But what if we stop propagating the event in bubble phase ?? If you do so, you'll see that all the handlers that run in capture phase are executed successfully whereas only those handlers in the bubble phase are executed which come before the handler that stop the propagation of the event. I'll leave this to you as an exercise.

As a result, we can say that when an event propagation is stopped in bubble phase, it will not propagate further only in bubble phase as it has already propagated in capture phase before. Whereas, when an event propagation is stopped in capture phase, it'll not propagate further in any phase as the bubble phase as it has already stopped propagating in capture phase and the bubble phase executes after that.

Tired of Reading or Just scrolled down ?? Don't worry, you can watch the video too..!!

That's all for now. So, today we read about Bubble and Capture phases in component events in depth. In the next post, we'll learn about container components, what are they ? and how we can use them ? If you liked this post, then subscribe to this blog and share among others in your network so that they can get benefit too. Also, make sure to give your feedback in comments.

Happy Trailblazing..!!

14 comments:

  1. The Amount of hardwork you put in your websites is excellent(both videos and written part).
    Thank You.
    Rahul,Can you make a tutorial on client side cache.Like, we do not hit the server side and use the client side cache as much as possible.Like, I have a requirement to do the filtering in the lightning data table using javascript methods.I had used setstorable.but it is not working.

    and Please update the topic you are going to cover next.

    ReplyDelete
    Replies
    1. Hi Aadit,

      Thank you for your feedback. Yes setStorable has it's own limitations it is not updated sometimes even when our data is updated on server. What I can recommend right now is to fetch all data at once on initial page load (depending on size) and then store it in an attribute and use that data to filter your table accordingly.

      Next post will be about application events as scheduled and there are some small lightning tags also that I wanted to explain so next videos are lined up for these topics. I'll keep your suggestion in future schedule for sure :-)

      Delete
  2. Excellent Rahul....Did a great Job..... really hats off to your patience and hardwork....

    ReplyDelete
    Replies
    1. Thank you so much..!! Do share it in your network too :-)

      Delete
  3. @Rahul Malhotra - This is by far the best explanation I have read around bubble and capture phase. No one has explained it so thoroughly and clearly. It has removed the long standing cloud of confusion that I had around this concept. Can't thank you enough for the amazing work you have done. Million thanks.

    Please keep this great work going. Thanks

    ReplyDelete
    Replies
    1. Thank You for such an amazing feedback..!! This is what really keeps me going and motivates me to post more :-)

      Delete
  4. Very well explained . Thanks for putting all your effort !

    ReplyDelete
    Replies
    1. Thank you for your feedback Animesh. Make sure to share it in your network :-)

      Delete
  5. Very nice and clear explanation about Bubble and Capture phase.You have made these Salesforce jargons easy to understand with very good examples. Thank you so much and lots of appreciation for your efforts. :)

    ReplyDelete
    Replies
    1. So happy to know that you liked it Gayatri :-) Thanks for reading..!!

      Delete
  6. Hello Rahul,
    No need to see other blogs for bubble & capture phase.
    Very well explained.

    Thanks for sharing..

    ReplyDelete
  7. Awsome explanation. .really well explained i would say better than trail head :)

    ReplyDelete
  8. Can you explain the last statement in the last paragraph? "and the bubble phase executes after that".

    I mean, when the event.stopPropagation(); is defined in capture phase, why would the event traverse and execute the handler in bubble phase? it gets stopped in capture phase itself isn't it?

    It was all crystal clear to me, thanks to the way you covered the topic, but I'm just confused with that last statement. I certainly want the cherry on the cake too..!!

    ReplyDelete
    Replies
    1. You're correct. It'll stop, by that statement I mean:

      When an event propagation is stopped in capture phase, it'll not propagate further in any phase as it has already stopped propagating in capture phase and the bubble phase executes after that.

      Delete