2
<!-- Head -->
<script src="https://wchat.freshchat.com/js/widget.js"></script>
<!-- Head -->
<script>
  window.fcWidget.init({
    token: "WEB_CHAT_TOKEN",
    host: "https://wchat.freshchat.com",
    externalId: "john.doe1987",     // user’s id unique to your system
    firstName: "John",              // user’s first name
    lastName: "Doe",                // user’s last name
    email: "john.doe@gmail.com",    // user’s email address
    phone: "8668323090",            // phone number without country code
    phoneCountryCode: "+1"          // phone’s country code
  });
</script>

I would like to pass User's first name and email into my js chat script. I know that I should be able to grab the customer session using the object manager like so:

<?php
    $customerSession = $om->get('Magento\Customer\Model\Session');
    if($customerSession->isLoggedIn()) {
        echo   $customerSession->getCustomer()->getId()."<br/>";  // get Customer Id
        echo   $customerSession->getCustomer()->getName()."<br/>";  // get  Full Name
        echo   $customerSession->getCustomer()->getEmail()."<br/>"; // get Email Name
      }  
?>

Would I pass the two variables by just echo'ing them out inside the quotations?

2 Answers 2

4

Assuming that this is a JavaScript Component in the Magento sense of the word, you can basically "insert" it into any HTML element.

Let's say you want to put your chat inside a div you can do something like

<div id="chatbox">
     data-mage-init='{"chatComponent":{}}'
</div>

Setting up the block

So in your block you would write a function called getCustomerId that basically returns the customer's ID from the Session.

But, don't use the object manager. You can just edit the constructor of your Block and get access to the Session that way, using dependency injection.

protected $customerSession;

public function __construct(
    Context $context,
    Session $customerSession,
    array $data = []
) {
    $this->customerSession = $customerSession;
    parent::__construct($context, $data);
}

public function getCustomerId() {
    return $customerSession->getCustomer()->getId();
}

Here's some details on data-mage-init

RequireJS and more

You'll notice that I used chatcomponent as your component name. You'll need to set up your requirejs-config.js file to reflect this.

Create a requirejs file at [module dir]/view/frontend/requirejs-config.js with the contents:

var config = {
    map: {
        '*': {
            chatComponent: 'Vendor_Module/js/chatbox'
        }
    }
};

This will look for a javascript file called chatbox.js at [module_dir]/view/frontend/web/js/chatbox.js

*EDIT: If you directly write from the block to the template, it won't work because of full page caching. Use the customerData component instead. *

Inside your chatbox.js file:

define([
    'uiComponent',
    'Magento_Customer/js/customer-data',
], function (Component, customerData) {

   var myId = customerData.get('id')
});

Why go to all this trouble?

You're going to want your chatbox set up properly as a magento JS component not only because it's consistent with the rest of the Magento ecosystem, but because there's big benefits to using RequireJS.

You can use jquery and underscore and other magento UI components with the guarantee that they will actually be loaded in and present, which you might not have with just a <script> tag.

7
  • Hi @Jorge1o1, yes this is a javascript component. Thank you for the very thought-out and detailed explanation.
    – getData
    Nov 26, 2018 at 16:41
  • I'm going to try and implement this today. @Jorge1o1, so there is no way just to add those two variables into that javascript and place it in the head?
    – getData
    Nov 26, 2018 at 19:29
  • 1
    @getData Rather than placing it into the head, you could do something like a <script> tag in the body that declares: window.data = $block->getData() and then in your widget.js use that data. The problem is, you run into all sorts of issues of whether the script has been initialized or not, and then if you have dependencies on other things like jQuery and Underscore it's a mess to make sure those initialize before your widget.js. That's why the requireJS and magento JS component system exists
    – Jorge1o1
    Nov 27, 2018 at 0:20
  • 2
    @Jorge1o1 You can't put session related data (customer id) into page's html because the page is in full page cache. Rather use sections.xml and read the customer specific data from local storage using customer-data.js from Magento_Customer. Nov 29, 2018 at 20:45
  • @obscure Can you elaborate on how to do this correctly with sections.xml?
    – getData
    Nov 30, 2018 at 20:37
0

First Create Block.php file

 <?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace yourcompany\yourmodule\Block;

use Magento\Framework\View\Element\Template;

/**
 * Main contact form block
 *
 * @api
 * @since 100.0.2
 */
class Block extends Template
{
    protected $_dir;
    protected $_storeManager;
    public $customerSession;
    /**
 * @param Template\Context $context
 * @param array $data
 */
public function __construct(Template\Context $context,
    \Magento\Framework\Filesystem\DirectoryList $dir,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
   \Magento\Customer\Model\Session $customerSession,
    array $data = [])
{
    parent::__construct($context, $data);
    $this->_dir = $dir;
    $this->customerSession = $customerSession;
    $this->_storeManager = $storeManager;
}

/**
 * Returns action url for contact form
 *
 * @return string
 */
public function getcustomerSession(){

    return $this->customerSession;
}

}

Then In your Template.phtml file

<?php

$customerSession = $block->getcustomerSession();

$customerid = $customerSession->getCustomerId() ??  '';
$customername = $customerSession->getCustomer()->getName() ??  '';
$customerEmail = $customerSession->getCustomer()->getemail() ?? '';

    <script>
   require([
    "jquery", 
    'underscore',
    'domReady!'
    ], function ($,_) {
      var id = "<?php echo $customerid ?>";
      var name = "<?php echo $customername ?>";
      var email = "<?php echo $customerEmail ?>";
    });

</script>

in your layout xml file you need to disable cache if you want to use this solution and want to pass php variables directly to js code.

<referenceContainer name="content">
        <block class="Yourcompany\Yourmodule\Block\Block.php" name="yourtheme" cacheable="false" template="yourcompant_module::yourtheme.phtml"> 
        </block>
    </referenceContainer>

Do something like this if you want to pass your php vairables into you js code and then Use id,name and email in you js code.

6
  • First customer that visits a catalog page will have it's ID available to the next ones. It's because of full page cache or Varnish cache on catalog pages. Description of this question does not specify it's a My Account page, cart page ,checkout page or other not cacheable page in FPC. Looks like it's a chat box that should show on every page. Dec 3, 2018 at 13:08
  • please check my edited answer(last few lines). you are right. You need to disable cache if you want to use php variables directly in to js code.
    – Ashar Riaz
    Dec 3, 2018 at 13:19
  • On all pages you need to disable full page cache ? Dec 3, 2018 at 14:00
  • i believe if you disable cache for that template then it should work. <block class="Yourcompany\Yourmodule\Block\Block.php" name="yourtheme" cacheable="false" template="yourcompant_module::yourtheme.phtml"> </block> . This code is disabling cache of specific template. So in your layout file just add cache=false for your template.
    – Ashar Riaz
    Dec 3, 2018 at 15:27
  • cacheable=false disables the full page cache of the entire page where the layout declaration (with cacheable=false) for this block is included. Dec 4, 2018 at 9:06

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.