web
You’re offline. This is a read only version of the page.
close
Skip to main content
Community site session details

Community site session details

Session Id : yX0RWJBwl+fT3co4ZPrEKm
Power Apps - Power Apps Pro Dev & ISV
Answered

Third party component in model driven app renders differently when editing custom page vs. when published

Like (0) ShareShare
ReportReport
Posted on 12 Apr 2024 17:13:21 by 24

Hi,

I'm creating a PowerApps model driven app using DataVerse.
I created a Blank App based on Dataverse, and then a custom page.
I imported my custom PCF React component that uses React.
This component uses a Bryntum React Gantt chart that I imported using npm. I want to add DataVerse data to it.

So far, I have got the context.webAPI to fetch data from a custom DataVerse table and I can render the Bryntum Gantt.

The problem is that the Bryntum Gantt React component is rendered when I am editing the custom page, but not in the published app. 
In the published app I get the following error:

 

 

Cannot read properties of undefined (reading 'cssVersion')
Error code: 0x0

or Details: TypeError: Cannot read properties of undefined (reading 'cssVersion')
 at Gantt.construct (webpack://pcf_tools_652ac3f36e1e4bca82eb3c1dc44e6fad/./node_modules/@bryntum/gantt/gantt.module.js?:13829:250)
 at Gantt.construct (webpack://pcf_tools_652ac3f36e1e4bca82eb3c1dc44e6fad/./node_modules/@bryntum/gantt/gantt.module.js?:29576:272)
 at Gantt.construct (webpack://pcf_tools_652ac3f36e1e4bca82eb3c1dc44e6fad/./node_modules/@bryntum/gantt/gantt.module.js?:32307:119)
 at Gantt.construct (webpack://pcf_tools_652ac3f36e1e4bca82eb3c1dc44e6fad/./node_modules/@bryntum/gantt/gantt.module.js?:32571:109)
 at Gantt.construct (webpack://pcf_tools_652ac3f36e1e4bca82eb3c1dc44e6fad/./node_modules/@bryntum/gantt/gantt.module.js?:33062:103)
 at Gantt.construct (webpack://pcf_tools_652ac3f36e1e4bca82eb3c1dc44e6fad/./node_modules/@bryntum/gantt/gantt.module.js?:39049:37)
 at Gantt.construct (webpack://pcf_tools_652ac3f36e1e4bca82eb3c1dc44e6fad/./node_modules/@bryntum/gantt/gantt.module.js?:39066:215)
 at Gantt.construct (webpack://pcf_tools_652ac3f36e1e4bca82eb3c1dc44e6fad/./node_modules/@bryntum/gantt/gantt.module.js?:53711:1436)
 at new _Base (webpack://pcf_tools_652ac3f36e1e4bca82eb3c1dc44e6fad/./node_modules/@bryntum/gantt/gantt.module.js?:1899:93)
 at new Localizable (webpack://pcf_tools_652ac3f36e1e4bca82eb3c1dc44e6fad/./node_modules/@bryntum/gantt/gantt.module.js?:3269:341)

 


The error source in gantt.module.js:

 

 

//region Init & destroy
 construct() {
 var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
 var me = this
 , {domSyncCallback} = me
 , {recomposeAsync} = _Widget;
 if (recomposeAsync != null && me.recomposeAsync == null) {
 me.recomposeAsync = recomposeAsync;
 }
 if (!globalThis.bryntum.cssVersion) {
 var cssVersion = globalThis.bryntum.cssVersion = CSSHelper.getCSSVersion()
 , jsVersion = VersionHelper.getVersion("core");
 if (cssVersion && cssVersion !== jsVersion) {
 console.warn("CSS version ".concat(cssVersion, " doesn't match bundle version ").concat(jsVersion, "!\nMake sure you have imported css from the appropriate product version."));
 }
 }

 

 

 

I can kind of fix the error by changing the globalThis object before the component is rendered:

 

 // Manually initialize the cssVersion if not present
 console.log('globalThis: ', globalThis);
// @TS-ignore 
 if (!globalThis.bryntum) {
 console.log('!globalThis.bryntum');
 
 // @TS-ignore
 globalThis.bryntum = {};
 }
 // @TS-ignore
 if (!globalThis.bryntum.cssVersion) {
 console.log('!globalThis.bryntum.cssVersion');
 // @TS-ignore
 globalThis.bryntum.cssVersion = '5.6.9'; // Ensure this matches the version of Bryntum Gantt you are using
 }

 


 I then have issues with the Bryntum Gantt component props being passed into the component.

What causes the difference in rendering in the published app? 

I have the same question (0)
  • a33ik Profile Picture
    3,304 Most Valuable Professional on 12 Apr 2024 at 17:18:31
    Re: Third party component in model driven app renders differently when editing custom page vs. when published

    Hello,

    I have 2 questions:

    1. What's globalThis

    2. Why do you run this code in the constructor and not in the "init"?

  • MattDC Profile Picture
    24 on 13 Apr 2024 at 08:14:54
    Re: Third party component in model driven app renders differently when editing custom page vs. when published
    1. I used globalThis based on a ChatGPT suggestion. I console.logged it in my PowerApps app - it's the global browser Window object.
      • Before your Gantt component initializes, ensure that globalThis.bryntum is defined and has a cssVersion. You can add a check or a default initialization in your component or script where the Bryntum component is used:Chat GPT suggestion:

        Initialize Bryntum Global Object:

    Here's my component code incase it's useful:

    ControlManifest.Input.xml

     

     <resources>
     <code path="index.ts" order="3"/>
     <platform-library name="React" version="16.8.6" />
     <platform-library name="Fluent" version="8.29.0" />
     <css path="css/BryntumGanttBasic.css" order="2" />
     <css path="../node_modules/@bryntum/gantt/gantt.stockholm.css" order="1" />
     </resources>

     

     

    index.ts

     

    import BryntumGanttBasicComponent, { IBryntumGanttBasicProps } from "./BryntumGanttBasicComponent";
    import { IInputs, IOutputs } from "./generated/ManifestTypes";
    import { HelloWorld, IHelloWorldProps } from "./HelloWorld";
    import * as React from "react";
    
    export class BryntumGanttBasic implements ComponentFramework.ReactControl<IInputs, IOutputs> {
     private theComponent: ComponentFramework.ReactControl<IInputs, IOutputs>;
     private notifyOutputChanged: () => void;
     // Reference to ComponentFramework Context object
     private _context: ComponentFramework.Context<IInputs>;
     /**
     * Empty constructor.
     */
     constructor() { }
    
     /**
     * Used to initialize the control instance. Controls can kick off remote server calls and other initialization actions here.
     * Data-set values are not initialized here, use updateView.
     * @Param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to property names defined in the manifest, as well as utility functions.
     * @Param notifyOutputChanged A callback method to alert the framework that the control has new outputs ready to be retrieved asynchronously.
     * @Param state A piece of data that persists in one session for a single user. Can be set at any point in a controls life cycle by calling 'setControlState' in the Mode interface.
     */
     public init(
     context: ComponentFramework.Context<IInputs>,
     notifyOutputChanged: () => void,
     state: ComponentFramework.Dictionary
     😞 void {
     this.notifyOutputChanged = notifyOutputChanged;
     this._context = context;
     }
    
     /**
     * Called when any value in the property bag has changed. This includes field values, data-sets, global values such as container height and width, offline status, control metadata values such as label, visible, etc.
     * @Param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to names defined in the manifest, as well as utility functions
     * @returns ReactElement root react element for the control
     */
     public updateView(context: ComponentFramework.Context<IInputs>): React.ReactElement {
     const props: IBryntumGanttBasicProps = { context: context };
     return React.createElement(
     // BryntumGanttBasicComponent, props as any
     BryntumGanttBasicComponent, props as any
     );
     }
    
     /**
     * It is called by the framework prior to a control receiving new data.
     * @returns an object based on nomenclature defined in manifest, expecting object[s] for property marked as "bound" or "output"
     */
     public getOutputs(): IOutputs {
     return { };
     }
    
     /**
     * Called when the control is to be removed from the DOM tree. Controls should use this call for cleanup.
     * i.e. cancelling any pending remote calls, removing listeners, etc.
     */
     public destroy(): void {
     // Add code to cleanup control if necessary
     }
     
    }

     

     

    BryntumGanttBasicComponent.tsx

     

    import * as React from 'react';
    import { FunctionComponent, useRef } from "react";
    import { ganttConfig } from "./GanttConfig";
    import { BryntumGantt as OriginalBryntumGantt } from '@bryntum/gantt-react';
    
    export interface IBryntumGanttBasicProps {
     context?: any;
    }
    
    const BryntumGantt: React.ComponentType<any> = OriginalBryntumGantt as any;
    
    const BryntumGanttBasicComponent: FunctionComponent = (props: any) => {
     const [data, setData] = React.useState("inital data state");
     const gantt = useRef<typeof BryntumGantt>(null);
     const [ganttConfig, setGanttConfig] = React.useState({
     columns: [{ type: "name", field: "name", width: 20 }],
     viewPreset: "weekAndDayLetter",
     barMargin: 10,
     });
     console.log({props}, props?.context);
     
     // Manually initialize the cssVersion if not present - hacky attempt to fix "Cannot read properties of undefined (reading 'cssVersion')" error 
     console.log('globalThis: ', globalThis);
    // @TS-ignore 
     if (!globalThis.bryntum) {
     console.log('!globalThis.bryntum');
     
     // @TS-ignore
     globalThis.bryntum = {};
     }
     // @TS-ignore
     if (!globalThis.bryntum.cssVersion) {
     console.log('!globalThis.bryntum.cssVersion');
     // @TS-ignore
     globalThis.bryntum.cssVersion = '5.6.9'; // Ensure this matches the version of Bryntum Gantt you are using
     }
     // @TS-ignore
     console.log('globalThis.bryntum.cssVersion: ', globalThis.bryntum.cssVersion);
     
     // Dynamically update configuration or perform additional setup after component has mounted
     React.useEffect(() => {
     console.log('useEffect called');
     setGanttConfig({
     columns: [{ type: "name", field: "name", width: 250 }],
     viewPreset: "weekAndDayLetter",
     barMargin: 10,
     });
     }, []); 
     
     const fetchRecords = async () => {
     console.log('fetch records function called');
     try { 
     console.log('fetchRecords try block');
     const res = await props?.context?.webAPI.retrieveMultipleRecords("cr8a7_test");
     console.log({res});
     console.log("Retrieved records: ", res.entities);
     setData(JSON.stringify(res.entities));
     }
     catch(e){
     console.log('fetchRecords catch block');
     if(e instanceof Error){
     setData(`Data fetch error: ${e.message}`);
     if(e.name === "PCFNonImplementedError"){
     console.log("PCFNonImplementedError: ", e.message);
     return [] //your fallback data for the designer
     }
     }
     throw e;
     }
     };
    
     return (
     <> 
     <div>component Bryntum Gantt rendered, change globalThis - fetch test data with correct logical name</div>
     <button onClick={fetchRecords}>Click to call WebAPI and show data (stored in state)</button>
     <div>WebAPI fetch data: {data}</div>
     <BryntumGantt ref={gantt} {...ganttConfig} />
     </>
    );
    };
    
    // If you plan to use stateful React collections for data binding please check this guide
    // https://bryntum.com/products/gantt/docs/guide/Gantt/integration/react/data-binding
    
    export default BryntumGanttBasicComponent;

     

     

  • MattDC Profile Picture
    24 on 15 Apr 2024 at 07:12:04
    Re: Third party component in model driven app renders differently when editing custom page vs. when published

    I found an unresolved forum post: [REACT] Correct way to load CSS from thin package, by someone who had a similar problem using Bryntum with Power Apps. It seems to be related to using the global window object in Power Apps. 

  • Verified answer
    MattDC Profile Picture
    24 on 12 May 2024 at 17:54:39
    Re: Third party component in model driven app renders differently when editing custom page vs. when published

    Adding the following line of code to the init() method fixed the issue:

     

    Object.defineProperty(window, "globalThis", { value : window, writable: false });

     

    There is an open Bryntum support ticket to fix this issue.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Tom Macfarlan – Community Spotlight

We are honored to recognize Tom Macfarlan as our Community Spotlight for October…

Leaderboard > Power Apps

#1
WarrenBelz Profile Picture

WarrenBelz 752 Most Valuable Professional

#2
developerAJ Profile Picture

developerAJ 472

#3
Michael E. Gernaey Profile Picture

Michael E. Gernaey 358 Super User 2025 Season 2

Last 30 days Overall leaderboard
Loading complete