Magento 2.4 newsletter using ajax

Magento 2.4 newsletter using ajax

Magento 2.4 newsletter using ajax, Customers subscribe to the newsletter in your store for any reason, they will get message near to newsletter.

Steps to AJAX Newsletter in Magento 2:

1 Create di.xml at MyVendor/MyModule/etc folder

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Newsletter\Controller\Subscriber\NewAction">
        <plugin name="custom_Subscriber_NewAction"
                type="MyVendor\MyModule\Plugin\Controller\Subscriber\NewAction" sortOrder="10" disabled="false" />
    </type>
</config>

2. Create NewAction.php at MyVendor/MyModule/Plugin/Controller/Subscriber folder

<?php

namespace MyVendor\MyModule\Plugin\Controller\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\Subscriber;
use Magento\Newsletter\Model\SubscriberFactory;
use Magento\Newsletter\Model\SubscriptionManagerInterface;
use Magento\Framework\Validator\EmailAddress as EmailValidator;
/**
 * Class NewAction
 */
class NewAction extends \Magento\Newsletter\Controller\Subscriber\NewAction
{
    /**
     * @var CustomerAccountManagement
     */
    protected $customerAccountManagement;

    protected $resultJsonFactory;

     private $emailValidator;

    /**
     * @var SubscriptionManagerInterface
     */

    private $subscriptionManager;

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

    /**
     * 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);


                $websiteId = (int)$this->_storeManager->getStore()->getWebsiteId();
                
                $subscriber = $this->_subscriberFactory->create()->loadBySubscriberEmail($email, $websiteId);
                
                if ($subscriber->getId()
                    && (int)$subscriber->getSubscriberStatus() === Subscriber::STATUS_SUBSCRIBED) {
                     $response = [
                        'status' => 'OK',
                        'msg' => 'This email address is already subscribed.',
                    ];
                    return $this->resultJsonFactory->create()->setData($response);
                }

                $status = $this->_subscriberFactory->create()->subscribe($email);
               
                if ($status == 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);
    }
}

3 In your newsletter.phtml file, add below code.

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

/** @var \Magento\Newsletter\Block\Subscribe $block */
?>
<div class="block newsletter">
    <h3><?= $block->escapeHtml(__('Newsletter')) ?></h3>
    <p><?= $block->escapeHtml(__('Join our mailing list for latest news and exclusive offers')) ?></p>

    <div class="content">
        <form class="form subscribe"  novalidate   action="<?= $block->escapeUrl($block->getFormActionUrl()) ?>"   method="post"  data-mage-init='{"validation": {"errorClass": "mage-error"}}'   id="newsletter-validate-detail">
            <div class="field newsletter">
                <div class="control">
                    <label for="newsletter">
                        <span class="label">
                            <?= $block->escapeHtml(__('Sign Up for Our Newsletter:')) ?>
                        </span>
                        <input name="email" type="email" id="newsletter"
                               placeholder="<?= $block->escapeHtml(__('Email address')) ?>"
                               data-mage-init='{"mage/trim-input":{}}'
                               data-validate="{required:true, 'validate-email':true}"
                        />
                    </label>
                </div>
            </div>
            <div class="actions">
                <button class="action subscribe primary"  title="<?= $block->escapeHtmlAttr(__('Subscribe')) ?>"  type="submit"   aria-label="Subscribe">
                    <span><?= $block->escapeHtml(__('Subscribe email')) ?></span>
                </button>
            </div>
            <div id="loading-message" style="display:none;padding-top:10px;color: white;font-size: 13px;font-weight: 500;">&nbsp;</div>
            <div class="scg-msg">
                <div class="messages">
                </div>
            </div>
        </form>
    </div>
</div>
<script type="text/x-magento-init">
    {
        "*": {
            "Magento_Customer/js/block-submit-on-send": {
                "formId": "newsletter-validate-detail"
            }
        }
    }
</script>
<script>
require(['jquery'],function($){
    var form = $('#newsletter-validate-detail');
    form.submit(function(e) {
        if(form.validation('isValid')){
            var email = $("#newsletter-validate-detail #newsletter").val();
            var url = form.attr('action');
            var loadingMessage = $('#loading-message');
              
            e.preventDefault();
            try{
                loadingMessage.html('Submitting...').show();
                $('.scg-msg > messages').html();

                $.ajax({
                    url: url,
                    dataType: 'json',
                    type: 'POST',
                    data: {email: email},
                    success: function (data){
                        if(data.status != "ERROR"){
                            $("#newsletter-validate-detail #newsletter").val('');                           
                            loadingMessage.css('color','green');
                        }else{                         
                            loadingMessage.css('color','red');
                        }                            
                        loadingMessage.html(data.msg);
                        setTimeout(function () {
                            loadingMessage.hide();
                            $("#newsletter-validate-detail .action.subscribe.primary").removeAttr('disabled');
                            $("#newsletter-validate-detail .action.subscribe.primary").prop("disabled", false);
                        }, 5000)
                    },
                });
            } catch (e){
                loadingMessage.css('color','red');
                loadingMessage.html('Something went worng!');
                setTimeout(function () {
                    loadingMessage.hide();
                    $("#newsletter-validate-detail .action.subscribe.primary").removeAttr('disabled');
                    $("#newsletter-validate-detail .action.subscribe.primary").prop("disabled", false);
                }, 5000)
            }
        }
    });
})
</script>

Using the above steps and you will get functional Ajax Newsletter in Magento 2

Feel free to mention them in the comments section below.

Related Post : Get Block Attribute Value In Phtml

Like us on Facebook and Linkedin for more updates.

Back To Top