25

I have a Module which processes a Post action, and then redirects.

Now there are error cases, and I would like to show messages for them to the users.

I already know, that this code adds the message to the session.

$this->messageManager->addError(
   $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($message)
);

But I dont see how to trigger the rendering.

Currently it is only shown when i execute another action, which already uses this in a working way.

Like for example the login with wrong password.

10

Not sure if this is what you are looking for, but I'm giving it a shot.
You can retrieve the messages like this:

$messages = $this->messageManager->getMessages(true);  

where messageManager is an instance of \Magento\Framework\Message\ManagerInterface.

In the core, this is used for ajax calls in order to return the error messages in the json response like this (\Magento\Catalog\Controller\Adminhtml\Category\Move):

$block = $this->layoutFactory->create()->getMessagesBlock();
...
$block->setMessages($this->messageManager->getMessages(true));
$resultJson = $this->resultJsonFactory->create();

return $resultJson->setData([
    'messages' => $block->getGroupedHtml(),
    'error' => $error
]);

For actions with output you shouldn't do anything (I think). The default.xml layout file from the Magento_Theme module already contains this block <block class="Magento\Framework\View\Element\Messages" name="messages" as="messages" template="Magento_Theme::messages.phtml"/> that should handle the messages.

[Side note]:
Don't use $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($message). Inject in your constructor an instance of Magento\Framework\Escaper and use that.

| improve this answer | |
  • The loginPost action is also able to trigger this, and it does a redirect to the login page after this and shows it then. Thats the case I have, too. No ajax, no same page. – Flyingmana Sep 15 '15 at 8:29
  • That's what I said...this should be handled by default. You should not need to make any changes. The session message should be displayed on the next page. – Marius Sep 15 '15 at 8:35
  • 2
    And thats why I do this question. Because its not. I even redirect to the same page(login) so obviously there is an additional step needed. As I said, even on the login page my message is only shown after i tried the login which posts its own message – Flyingmana Sep 15 '15 at 8:38
  • 1
    OK. I'll dig deeper. This looks strange to me. – Marius Sep 15 '15 at 8:39
  • 1
    @Flyingmana. I found something. The session messages are retrieved after a call is made to /customer/section/load/. Maybe that helps. – Marius Sep 15 '15 at 9:31
25

You need to use object injection method on ur module action class to inject the message manager object into it, i provided an example of what u can do. Hope it helps

class Example
{
    protected $_messageManager;

    public function __construct(
        \Magento\Framework\Message\ManagerInterface $messageManager
    ) {
        $this->_messageManager = $messageManager;
    }

    public function method( ) {
        ..
        $message = '...';
        $this->_messageManager->addError($message);
        ..
    }
}
| improve this answer | |
  • is there any getError function? i want to fetch the message – jafar pinjar Oct 25 '18 at 7:08
  • 1
    the addError method is deprecated should be addErrorMessage now – jamil Nov 21 '18 at 17:56
  • @jafarpinjar , nope. I would change it in translation , but if you cant change it in translation, you can get the error message by event observer and manipulate it there. – Karvin Ong Jun 7 '19 at 1:45
  • @jamil , yes agreed. addError is depreciated but still supported on ver 2.3.1 :) – Karvin Ong Jun 7 '19 at 1:47
5

you can also find the message manager accessible through $context that is injected into actions constructors:

class yourAction extends \Magento\Framework\App\Action\Action
{
    /** var ... */
    protected $_messageManager;

    public function __construct(Context $context)
    {
        $this->_messageManager = $context->getMessageManager();
        parent::__construct($context);
    }

Next just use as mentioned in answers above

$this->_messageManager->addError($message);

Hope it helps

| improve this answer | |
2

For me it looks like you need to add special block for your messages if you want to show them in non-JS way.

For example in Magento\Checkout\view\frontend\layout\checkout_cart_index.xml there is:

<referenceContainer name="page.messages">
    <block class="Magento\Checkout\Block\Cart\ValidationMessages" name="checkout.cart.validationmessages"/>
</referenceContainer>

Magento\Checkout\Block\Cart\ValidationMessages block extends core \Magento\Framework\View\Element\Messages block which is responsible for rendering messages.

Blocks defined in default.xml are for JS messages only I believe.

| improve this answer | |
  • How do you add it to checkout_index_index.xml? – stephen Apr 7 '17 at 13:35
1

Take a look at

vendor/magento/module-customer/view/frontend/web/js/customer-data.js

/**
 * Events listener
 */
$(document).on('ajaxComplete', function (event, xhr, settings) {
    var sections,
        redirects;

    if (settings.type.match(/post|put/i)) {
        sections = sectionConfig.getAffectedSections(settings.url);

        if (sections) {
            customerData.invalidate(sections);
            redirects = ['redirect', 'backUrl'];

            if (_.isObject(xhr.responseJSON) && !_.isEmpty(_.pick(xhr.responseJSON, redirects))) {
                return;
            }
            customerData.reload(sections, true);
        }
    }
});

As we can see, there is a built-in checking function already. If our response contains keywords: 'redirect', 'backUrl', the message will load after redirecting.

  • After ajax complete, the customer will be invalidated. This will be "trigger" reloading message session.
  • Checking keywords: 'redirect', 'backUrl'.
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.