0

I am building a custom widget that I want to display specific products based on the product SKU. I have tried a few different code examples to get products using the dependency injection method, but when I try to get the product name, it errs.

Error: Call to a member function getName() on null

The products I am trying to get are all enabled and exist in the database, so I don't see any reason for it to not be able to get the name.

Not sure what exactly I'm missing ...

These are the tutorials I have looked at:

https://www.magetrend.com/blog/magento-2-get-product-by-sku-or-id/

https://magecomp.com/blog/load-products-by-id-and-sku-in-magento-2/

https://www.hiddentechies.com/blog/magento-2/magento-2-get-product-by-sku/

/app/code/Vendor/Module/etc/widget.xml

<?xml version="1.0" ?>
<widgets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Widget:etc/widget.xsd">
<widget class="Vendor\Module\Block\Widget\Featuredproducts" id="vendor_module_featuredproducts">
    <label>Featured Products</label>
    <description>Enter SKUs for products to feature</description>
    <parameters>
        <parameter name="featuredproductsid" sort_order="10" visible="true" xsi:type="text">
            <label>SKUs (comma separated)</label>
        </parameter>
    </parameters>
</widget>
</widgets>

app/code/Vendor/Module/Block/Widget/Featuredproducts.php

<?php
namespace Vendor\Module\Block\Widget;

use Magento\Framework\View\Element\Template;
use Magento\Widget\Block\BlockInterface;

class Featuredproducts extends Template implements BlockInterface
{
    protected $_template = "widget/featuredproducts.phtml";
}

/app/code/Vendor/Module/Block/Widgets.php

<?php
  namespace Vendor\Module\Block;

 class Widgets extends \Magento\Framework\View\Element\Template
 {  
  public $_productRepository;
    
public function __construct(
    \Magento\Backend\Block\Template\Context $context,       
    \Magento\Catalog\Model\ProductRepository $productRepository,
    array $data = []
)
{
    $this->_productRepository = $productRepository;
    parent::__construct($context, $data);
}

public function getProductById($id)
{
    return $this->_productRepository->getById($id);
}

public function getProductBySku($sku)
{
    return $this->_productRepository->get($sku);
}
}
?>

/app/code/Vendor/Module/view/frontend/templates/widget/featuredproducts.phtml

<?php if($block->getData('featuredproductsid')): 

  $featuredSkus = $block->getData('featuredproductsid'); 
  $arr_featuredSkus = explode(',', $featuredSkus);?>

 <div class="featured-products-rotator">
   <?php foreach($arr_featuredSkus as $sku) { 

    $prod = $block->getProductDataUsingSku($sku); ?>

    <a href="#" class="product-content">
      <span class="headline"><?php echo $prod->getName(); ?></span>
    </a>

  <?php } ?>
  </div>
<?php endif; ?>

--

When I use the ObjectManager method, each of the items list as expected.

$product = \Magento\Framework\App\ObjectManager::getInstance()
        ->create(\Magento\Catalog\Model\Product::class)
        ->loadByAttribute('sku', $sku);

I want to use the dependency injection method, as that is the recommended way to do it. Totally stumped ...

2 Answers 2

2

After making the change that @simonthesorcerer suggested, I ended up deleting my widgets.php file and adding the content that was in it to the Featuredproducts.php file.

The featuredproducts.php now looks like this:

namespace Vendor\Module\Block\Widget;

use Magento\Framework\View\Element\Template;
use Magento\Widget\Block\BlockInterface;

class Featuredproducts extends Template implements BlockInterface
{
protected $_template = "widget/featuredproducts.phtml";

protected $_productRepository;
    
public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,      
    \Magento\Catalog\Model\ProductRepository $productRepository,
    array $data = []
)
{
    $this->_productRepository = $productRepository;
    parent::__construct($context, $data);
}

public function getProductById($id)
{
    return $this->_productRepository->getById($id);
}

public function getProductBySku($sku)
{
    return $this->_productRepository->get($sku);
}

}
1

method getProductDataUsingSku is undefined, which means it falls back on the magic __get() method. Replace it in your template with getProductBySku

1
  • Unfortunately, that did not work. Ran all the setup:upgrade and cache clearing stuff.
    – cjochum
    Sep 23, 2021 at 16:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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