Magento 2 Admin UI Component Grid loads data but columns are not rendered (columns component not registered)

Summary

We encountered an empty Admin grid where data was successfully fetched by the datasource, but no column headers or rows were rendered. The uiRegistry confirmed the listing and datasource components were registered, but the columns component was missing (undefined). The root cause was a mismatch between the spinner configuration item and the name attribute of the <columns> XML node, combined with a missing or incorrect columns provider dependency in the listing configuration.

Root Cause

The immediate cause of the failure is that the Magento UI component processor cannot resolve the columns component instance because it is not correctly linked to the listing component’s configuration.

Specifically, in the provided XML:

  1. The <argument name="data"> block defines a spinner key with value refund_columns.
  2. The <columns> node defines a name attribute of refund_columns.
  3. However, the listing component expects to find a columns component registered under a specific path (usually market_refund_listing.market_refund_listing.columns).
  4. Because the spinner logic or the columns provider dependency is not explicitly defined or pointing to the correct component instance, the columns component is never instantiated as a child of the listing component, resulting in uiRegistry returning undefined for the columns path.

Why This Happens in Real Systems

Magento’s UI components rely on a strict Hierarchical Registry and Dependency Injection system.

  • Dependency Resolution: The listing component (Magento_Ui/js/grid/listing) often initializes its children (like the columns component) based on configuration dependencies defined in js_config.
  • Spinner/Columns Link: The spinner argument is used by the grid UI to show loading states. If the value provided to spinner does not map correctly to the instantiated child component tree, the grid logic fails to locate the container for rendering headers and rows.
  • Asynchronous Loading: While the data source is independent, the structural components (columns) must be resolved synchronously during the RequireJS define and init phases. If a dependency is missing in requirejs-config.php or ui_component XML, the class definition for the columns is never loaded.

Real-World Impact

  • Operational Blocker: Admin users cannot view, sort, filter, or edit data in the grid, effectively breaking backend management for that entity.
  • Silent Failure: The page loads without JavaScript errors, making this difficult to debug for junior developers.
  • Data Integrity Risk: Users might assume no data exists because the grid is empty, leading to duplicate record creation or missed refunds.

Example or Code

The problem lies in the configuration structure. Below is the corrected XML structure that ensures the columns component is instantiated and linked correctly.



    
        
            market_refund_listing.market_refund_listing_data_source
            market_refund_listing.market_refund_listing_data_source
        
        
        refund_columns
    

    
       
    

    
    
        
            
                full
            
        
        
            
                
                text
                asc
            
        
        
            
                
                text
            
        
        
            
                
                text
            
        
        
            
                
                text
            
        
        
            
                
                dateRange
            
        
    

How Senior Engineers Fix It

Senior engineers approach this by verifying the UI Component Tree and Dependencies:

  1. Inspect the Registry: Use require('uiRegistry').get('market_refund_listing') to inspect the instantiated listing object. Check the children property to see if refund_columns or columns exists.
  2. Align name and spinner: Ensure the spinner configuration item in the listing argument matches the name attribute of the <columns> XML node exactly.
  3. Explicit js_config deps: If the columns component is not loading, explicitly add a dependency in the listing’s <argument name="data">...<js_config>...<deps> if available, or ensure the columns component is defined as a sibling to the dataSource within the <listing> tag.
  4. Check Layout XML: Verify that the uiComponent name in the Layout XML matches the file name and the root name attribute in the UI Component XML.

Why Juniors Miss It

  • Focus on Data Source: Juniors often debug the PHP DataProvider endlessly because the data is not rendering, assuming the issue is backend.
  • Missing “invisible” Dependencies: They assume that defining <columns> in XML is sufficient. They miss that the spinner or js_config linking acts as the “glue” that actually instantiates the columns object in the browser.
  • No Console Errors: Since the file loads and the data request succeeds, the browser console remains clean, providing false confidence that the code is correct.
  • Copy-Paste Errors: Often, the name attribute in columns is changed (e.g., to refund_columns) but the spinner argument in the main listing block is left as the default columns or mismatched, breaking the link.