I'm trying to render some javascript when the customer_login
event fires by accessing a block on the layout from within the observer.
I've successfully registered my observer to execute with the event and that works fine.
The problem I'm running into is that when I attempt to access a specific block object from within the observer the layout does not contain any block elements.
I'm mimicking code that I've seen in the magento2 google analytics plugin that sets a value on a block object from an observer registered on the checkout_onepage_controller_success_action
event.
My guess for why this isn't working is that this event fires before any of the block elements are initialized and registered with the layout.
If this is the case and my current approach is not a valid one how would I go about rendering some javascript when this event fires?
etc/frontend/events.xml:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="customer_login">
<observer name="login_success" instance="Companyname\Revjs\Observer\SetCompanynameLoginSuccessObserver" />
</event>
</config>
Observer/SetCompanynameLoginSuccessObserver.php:
<?php
namespace Companyname\Revjs\Observer;
use Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\Event\ObserverInterface;
class SetCompanynameLoginSuccessObserver implements ObserverInterface
{
/**
* @var \Magento\Framework\View\LayoutInterface
*/
protected $layout;
/**
* @param \Magento\Framework\View\LayoutInterface $layout
*/
public function __construct(
\Magento\Framework\View\LayoutInterface $layout
) {
$this->layout = $layout;
}
public function execute(EventObserver $observer)
{
$email = $observer->getEvent()->getCustomer()->getEmail();
if (!$email) {
return;
}
// this call returns false rather than a block object
$block = $this->layout->getBlock('companyname');
$block->setEmail($email);
}
}
view/frontend/layout/default.xml:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="after.body.start">
<block class="Companyname\Revjs\Block\Rv" name="companyname" as="companyname" template="rv.phtml"/>
</referenceContainer>
</body>
</page>
Block/Rv.php:
namespace Companyname\Revjs\Block;
class Rv extends \Magento\Framework\View\Element\Template
{
public function getEmailJsFunction()
{
$email = $this->getEmail();
if ($email) {
return sprintf("someJsFunction('%s');", $email);
} else {
return '';
}
}
}
view/frontend/templates/rv.phtml:
<script>
<?php echo $block->getEmailJsFunction(); ?>
</script>
Best Answer
you cannot access the blocks in the layout because there are no blocks in the layout.
The
customer_login
event is dispatched on aPOST
action that does not have output.TO overcome this, you can, in your observe, add just something to the session and in you block just check if there is that value in the session.
If there is, use it and remove it.