6

I am overriding the layout and adding ViewModel in that layout but when I try to fetch the ViewModel getting below error

PHP Fatal error: Uncaught Error: Call to a member function getCodes() on null

My XML files look life which resides under

/app/design/frontend/Custom/Theme/Magento_Review/layout/override/base/review_product_list.xml

    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">+
   <body>
        <referenceBlock name="product_additional_data">
            <arguments>
                <argument name="view_model" xsi:type="object">Custom\ProductModel\ViewModel\LocaleInfo</argument>
            </arguments>
        </referenceBlock>
     </body>
</page>

and my ViewModel resides under

Custom/ProductModel/ViewModel/LocaleInfo.php

and files look like

use Magento\Framework\View\Element\Block\ArgumentInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Locale\Resolver as LocaleResolver;
use Magento\Store\Model\ScopeInterface;

class LocaleInfo implements ArgumentInterface
{
    protected $scopeConfig;
    protected $localeResolver;

    public function __construct(
        ScopeConfigInterface $scopeConfig,
        LocaleResolver $localeResolver
    ) {
        $this->scopeConfig = $scopeConfig;
        $this->localeResolver = $localeResolver;
    }

    public function getCodes($storeId = null)
    {
        $configPath = $this->localeResolver->getDefaultLocalePath();
        $localeCode = $this->scopeConfig->getValue($configPath, ScopeInterface::SCOPE_STORE, $storeId);

        return $localeCode;
    }
}

trying to fetch like below

$myViewModel = $block->getViewModel();
echo $myViewModel->getCodes();
4
  • Please provide the phtml file location and also do you have namespace declaration like namespace Custom\ProductModel\ViewModel; ? You also need to clear your caches and perform compilation May 25, 2018 at 9:33
  • app/design/frontend/Custom/Theme/Magento_Review/templates/product/view/list.phtml thats the phtml file location
    – Daniel_12
    May 25, 2018 at 10:10
  • Yes I have declared namespace as well
    – Daniel_12
    May 25, 2018 at 10:10
  • try with $myViewModel = $block->getData('view_model'); instead of $myViewModel = $block->getViewModel();
    – Marius
    Dec 12, 2019 at 7:05

5 Answers 5

0

This is the block you are referencing in your layout handle XML file.

<block class="Magento\Review\Block\Product\View\ListView" 
       name="product.info.product_additional_data" 
       as="product_additional_data" 
       template="Magento_Review::product/view/list.phtml"
/>

You are referencing this block with its alias name; i.e, product_additional_data which is wrong. You should refer it with its name; i.e, product.info.product_additional_data.

So you should change your code like this:

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">+
   <body>
        <referenceBlock name="product.info.product_additional_data">
            <arguments>
                <argument name="view_model" xsi:type="object">Custom\ProductModel\ViewModel\LocaleInfo</argument>
            </arguments>
        </referenceBlock>
     </body>
</page>

After this changes made please clear your cache and then you are good to go.

EDIT

Your layout update XML file location also seems wrong. It should be like:

app/design/frontend/Custom/Theme/Magento_Review/layout/review_product_list.xml

9
  • No luck :( still have same error nothing change
    – Daniel_12
    May 25, 2018 at 11:54
  • @Daniel_12 see my edit. May 25, 2018 at 11:57
  • I am overriding layout and I think its location is correct. check this link devdocs.magento.com/guides/v2.2/frontend-dev-guide/layouts/…
    – Daniel_12
    May 25, 2018 at 12:05
  • But I tried as you say but still no luck same error
    – Daniel_12
    May 25, 2018 at 12:05
  • @Daniel_12 you here did a theme override. So the location should be as shown in my answer. You can see that in the given link too. With this, your code should work. I cannot see any other mistakes. check your logs for any errors. May 25, 2018 at 12:07
0

instead of view_model please write viewModel

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">+
   <body>
       <referenceBlock name="product_additional_data">
            <arguments>
                 <argument name="viewModel" xsi:type="object">Custom\ProductModel\ViewModel\LocaleInfo</argument>
             </arguments>
        </referenceBlock>
   </body>
</page>
0

I also faced the same situation and it worked once I used the view model argument name with underscore. Same as below as per the M2 Docs.

<referenceBlock name="checkout.cart.item.renderers.default">
    <arguments>
        <argument name="view_model" xsi:type="object">OrangeCompany\Catalog\ViewModel\MyNewViewModel</argument>
    </arguments>
</referenceBlock>

Reference: https://devdocs.magento.com/guides/v2.4/extension-dev-guide/view-models.html

Because on phtml file it was only possible to use $block->getViewModel() when we use name="view_model" otherwise we couldn't access this instance using get() instead of that we may have to use getData('unique_name').

In your sample code, I notice that <referenceBlock name="product_additional_data"> but I think it should be <referenceBlock name="product.additional.data"> as per the M2 Docs and also it should be the same name where that you refer the block name.

Cheers!

0

I was facing an issue where my view_model was working fine on product detail page for app/design/frontend/Vendor/theme-default/Magento_Catalog/templates/product/price/final_price.phtml, but $block->getData('view_model') was null on list page. Then after digging a bit I added this code inside catalog_category_view.xml for frontend and it worked. Passed the viewModel class referencing product.price.render.default block.

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
    <referenceBlock name="product.price.render.default">
        <arguments>
            <argument name="view_model" xsi:type="object">Vendor\Module\ViewModel\PriceInfo</argument>
        </arguments>
    </referenceBlock>
</body>
0

Basicly the process is

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
   <body>
        <referenceBlock name="block.name">
            <arguments>
                <argument name="my_view_model" xsi:type="object">Vendor\Module\Model\ViewModel\MyViewModel</argument>
            </arguments>
        </referenceBlock>
     </body>
</page>

Your Class MyViewModel should implement Magento\Framework\View\Element\Block\ArgumentInterface

Then in the block you can get your view model by

$block->getData('my_view_model');

or

$block->getMyViewModel();

Be careful to not use too simplistic names like "view_model" cause you may override something that is needed in the page.

In the case that the above is not working, make sure there is no plugin that removes data from the block itself.

Your Answer

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

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