checkout_cart_save_before event, this way it will serve the correct cart page as well as handling calculating the totals correctly.
Breakdown on why
The logic that decides what page you get served is in the following method
Magento\Checkout\Block\Cart->getItemsCount() which in turn calls
getItemsCount on the quote.
If the method returns a truthy value, you will get served the cart with the sidebar otherwise you get the one without.
items_count data property on the quote is only, with the exception of the dot mailer module, set when you collect totals for the quote in
Magento\Quote\Model\Quote\TotalsCollector->_collectItemsQtys() which is fired from the
collect method within the same class.
The order of execution for saving the cart is as follows: (removed unrelated bits for simplicity)
- Dispatch Event
- Set Billing/Shipping Address
- Collect Totals (Here
items_count is set)
- Dispatch Event
So as you can see by using the
checkout_cart_save_after event, your code is fired after the totals are collected. Meaning the cart totals/items count is still set as the values before you removed the items.
And I believe (don't quote me on this) where the totals on the cart are loaded with ajax, this recalls the method to collect the totals. Which then causes the ajax'd totals to pull the correct
items_count and totals through. Although at this point its too late since the cart is already rendered.
Ideally, if you want to modify the items in the quote you would use the before event
checkout_cart_save_before so when it calculates the shipping rates/totals if takes into account your changes.
Or you could recollect the totals after you've made your changes in the after event.
Or you can manually update the
items_count value on the quote after you remove an item from it like you are currently doing.