In this article I will show you how to make ajax calls when a user tries to subscriber to the newsletters in Magento 2. On the code below I’m using the version 2.1 and I will take in consideration you already have/know how to implemented an custom module.

Firstly, let’s create a plugin to overwrite the Controller and Action that manage the requests in Magento. In your custom module add the following code to your di.xml file. It should be some where in app/code/NAMESPACE/MODULE/etc/di.xml.

    <type name="Magento\Newsletter\Controller\Subscriber\NewAction">
        <plugin name="Newsletter_Subscriber_NewAction"
                type="Namespace\Module\Controller\Plugin\Subscriber\NewAction" sortOrder="10" disabled="false" />
    </type>

Now lets create the file “app/code/Namespace/Module/Controller/Plugin/Subscriber/NewAction.php”, and add the following content:

<?php
/**
 *
 */
namespace Namespace\Module\Controller\Plugin\Subscriber;

use Magento\Customer\Api\AccountManagementInterface as CustomerAccountManagement;
use Magento\Customer\Model\Session;
use Magento\Customer\Model\Url as CustomerUrl;
use Magento\Framework\App\Action\Context;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Newsletter\Model\SubscriberFactory;

/**
 * Class NewAction
 */
class NewAction extends \Magento\Newsletter\Controller\Subscriber\NewAction
{
    /**
     * @var CustomerAccountManagement
     */
    protected $customerAccountManagement;

    protected $resultJsonFactory;

    /**
     * Initialize dependencies.
     *
     * @param Context $context
     * @param SubscriberFactory $subscriberFactory
     * @param Session $customerSession
     * @param StoreManagerInterface $storeManager
     * @param CustomerUrl $customerUrl
     * @param CustomerAccountManagement $customerAccountManagement
     */
    public function __construct(
        Context $context,
        SubscriberFactory $subscriberFactory,
        Session $customerSession,
        StoreManagerInterface $storeManager,
        CustomerUrl $customerUrl,
        CustomerAccountManagement $customerAccountManagement,
        \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
    ) {
        $this->customerAccountManagement = $customerAccountManagement;
        $this->resultJsonFactory = $resultJsonFactory;
        parent::__construct(
            $context,
            $subscriberFactory,
            $customerSession,
            $storeManager,
            $customerUrl,
            $customerAccountManagement
        );
    }

    /**
     * Retrieve available Order fields list
     *
     * @return array
     */
    public function aroundExecute($subject, $procede)
    {
        $response = [];
        if ($this->getRequest()->isPost() && $this->getRequest()->getPost('email')) {
            $email = (string)$this->getRequest()->getPost('email');

            try {
                $this->validateEmailFormat($email);
                $this->validateGuestSubscription();
                $this->validateEmailAvailable($email);

                $status = $this->_subscriberFactory->create()->subscribe($email);
                if ($status == \Magento\Newsletter\Model\Subscriber::STATUS_NOT_ACTIVE) {
                    $response = [
                        'status' => 'OK',
                        'msg' => 'The confirmation request has been sent.',
                    ];
                } else {
                    $response = [
                        'status' => 'OK',
                        'msg' => 'Thank you for your subscription.',
                    ];
                }
            } catch (\Magento\Framework\Exception\LocalizedException $e) {
                $response = [
                    'status' => 'ERROR',
                    'msg' => __('There was a problem with the subscription: %1', $e->getMessage()),
                ];
            } catch (\Exception $e) {
                $response = [
                    'status' => 'ERROR',
                    'msg' => __('Something went wrong with the subscription.'),
                ];
            }
        }

        return $this->resultJsonFactory->create()->setData($response);
    }

}

As you can see, I’m overwriting the method execute() and returning an Ajax response. Change it if you want a different approach.

Now let’s change the Front-end. Make a copy of “vendor/magento/module-newsletter/view/frontend/templates/subscribe.phtml” and place it inside your Magento Theme (e.g. app/design/frontend/NAMESPACE/MY_CUSTOM_THEME/Magento_Newsletter/templates/subscribe.phtml.

Add the following javascript to the end of the subscribe.phtml:

    {
        "*": {
            "js/newsletter_subscriber_ajax": { }
        }
    }

As you can see above, we are now calling a javascript file called “newsletter_subscriber_ajax.js”. It should be place in app/design/frontend/NAMESPACE/MY_CUSTOM_THEME/web/js/newsletter_subscriber_ajax.js and having the following content:

require.config({
    deps: [
        'jquery'
    ],
    callback: function ($) {
        var form = $('form.subscribe');

        form.submit(function(e) {
            if(form.validation('isValid')){
                var email = $("#newsletter").val();
                var url = form.attr('action');
                var loadingMessage = $('#loading-message');

                if(loadingMessage.length == 0) {
                    form.find('.control').append('<div id="loading-message" style="display:none;padding-top:10px;">&nbsp;</div>');
                    var loadingMessage = $('#loading-message');
                }

                e.preventDefault();
                try{
                    loadingMessage.html('Submitting...').show();
                    $.ajax({
                        url: url,
                        dataType: 'json',
                        type: 'POST',
                        data: {email: email},
                        success: function (data){
                            if(data.status != "ERROR"){
                                $('#newsletter').val('');
                            }
                            loadingMessage.html(data.msg);
                        },
                        complete: function(){
                            setTimeout(function(){
                                loadingMessage.hide();
                            },5000);
                        }
                    });
                } catch (e){
                    loadingMessage.html(e.message);
                }
            }
            return false;
        });
    }
})

It should work once you refresh the static files and clean the cache. If you’re on a dev environment, you can run this in your magento root folder:

rm -rf pub/static/* var/generation/* && php bin/magento cache:clean

That’s it. No more refreshing the whole page for your newsletter subscribers.

Happy Coding!

Magento 2 Newsletter Subscription via Ajaxhttps://i2.wp.com/blog.mdnsolutions.com/wp-content/uploads/2016/06/Screen-Shot-2016-06-24-at-10.47.27-AM.png?fit=645%2C307&ssl=1https://i2.wp.com/blog.mdnsolutions.com/wp-content/uploads/2016/06/Screen-Shot-2016-06-24-at-10.47.27-AM.png?resize=150%2C150&ssl=1Renato MedinaMagentoMagento 2Ajax,Magento 2,Newsletter,SubscriberIn this article I will show you how to make ajax calls when a user tries to subscriber to the newsletters in Magento 2. On the code below I'm using the version 2.1 and I will take in consideration you already have/know how to implemented an custom module. Firstly, let's create a...A Magento Craftsman in Melbourne