cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
SumitThakran
Helper I
Helper I

PCF Control giving error when its added in Form on Dynamics 365 Platform

Hi,

 

I have developed custom PCF Control in Typescript . I have used some React JS code to open React-Modal as popup window in Control Button Click.

This custom PCF Control is running fine when i am running it locally i.e from Visual Studio code. But when i deployed PCF Control to my Dynamics 365 environment.

And tried to access control in CRM Form then getting below error show in screenshot

 

SumitThakran_0-1592825011737.png

 

 

Basically i have used React js inside my Typescript project. I have used React-Modal component for showing popup window .

i did some analysis and found that when i remove Modal tsx file from my PCF Control and deployed simple component on Dynamics 365 platform then this error is not coming .

 

Can anyone tell me what i am doing wrong while calling Modal component or in its contructor.

So below is my piece of code i wrote it down to call my Modal component. Basically passing one parameter to Modal Component.

<MyModal inputABN = {this.state.inputValue}/>

 

And below is constructor of My Modal component.

export class MyModal extends React.Component<ModalProps, any> {
constructor (props: ModalProps) {
super(props);
this.state = {
showModal: false , inputABN: props.inputABN
};
............................

 

 

Any Help will be appreciated

 

 

Thanks

1 ACCEPTED SOLUTION

Accepted Solutions

Hi! As I mentioned early on the first reply. Remove this piece of code.

 

ReactModal.setAppElement('#app-root');

 

Because you don't have an HTML to set default <div> for the app, the <div> is given when the control is initialized. Like you create a react page project. When I remove this code works fine. 

 

If works, please mas as solution

View solution in original post

10 REPLIES 10
Michaelfp
Advocate II
Advocate II

Hi!

have you created an interface that extends ComponentState from react?

 

for example:

export interface ClassState extends React.ComponentState{}

export interface IExampleProps {
  prop1?: number;
  prop2?: (newValue: number) => void;
}
export default ComponentClass extends<IExampleProps ,ClassState>{
   constructor(props:IExampleProps){
      super(props);
   }
   public render(): JSX.Element{
      return();//here put the JSX content
   }
}

Hi Michael,

 

Thanks for you reply.

 

I have tried by creating interface also for props and state parameter in modal class.

Below is my Code for modal class .

 

export interface IModalProps {
  inputABN?: string;
  onInputChanged?:(newValue:string)=>void;
};
export interface IModalState extends React.ComponentState,IModalProps{}

ReactModal.setAppElement('#app-root');
export class MyModal extends React.Component<IModalProps, IModalState> {
  constructor (props: IModalProps) {
    super(props);
    this.state = {
      showModal: false , inputABN: props.inputABN
    };

    this.handleOpenModal = this.handleOpenModal.bind(this);
    this.handleCloseModal = this.handleCloseModal.bind(this);
  }
.....................................................
 
And this is how i am calling Modal component in another file.
<MyModal inputABN = {this.state.inputValue}/>
 
Can you point out whats wrong here in my code.
 
Thanks

why are put this loosely ReactModal.setAppElement('#app-root'); ?

 

in the react with PCF, the root control is the container that is given on the Init().

Can you share you index.ts?

I Create one for you. Can you test, please?

 

Create File ModalControl.tsx

import * as React from 'react';
import * as ReactDOM from "react-dom";

export interface ShowModalState
    extends React.ComponentState {
        show: boolean;
     }
export class ShowModal extends React.Component<{}, ShowModalState>{
    public state:ShowModalState;

    constructor(props: any) {
        super(props);
        this.state = {show:false};
        this.onClickHandler = this.onClickHandler.bind(this);
    }

    public onClickHandler(evt: React.MouseEvent) {
        evt.preventDefault();
        this.setState(prev => ({
            show: !prev.show
        }));
    }

    public render(): JSX.Element{
        const { show } = this.state;
        const styles = show ? "modal display" : "modal";
       
        return (
            <div id="modal-root">
            <button className="btn" onClick={this.onClickHandler} type="button">open modal</button>
            <div>
                <div id="modal" className={styles}>
                    <div className="modal-content">
                        <div className="modal-header"><span role="button" onClick={this.onClickHandler} className="btn-close">&times;</span>
                            <h2>Modal Header</h2>
                        </div>
                        <div className="modal-body">
                            <p>Body</p>
                        </div>
                        <div className="modal-footer">
                            <p>Footer</p>
                        </div>
                    </div>
                </div>
            </div>
          </div>
        );
    }
}

 

Create a CSS file Modal.css

.modal {
    display: none;
    position: fixed;
    z-index: 1;
    left: 50;
    top: 0;
    width: 50%;
    height: 50%;
    overflow: auto;
    background-color: rgb(0, 0, 0);
    background-color: rgba(0, 0, 0, 0.4);
    border: #fff solid 1px;
}

.display {
    display: block;
}

.modal-header {
    padding: 2px 16px;
    background-color: #742774;
    color: white;
}

.modal-body {
    padding: 2px 16px;
}

.modal-footer {
    padding: 2px 16px;
    background-color: #742774;
    color: white;
    margin-top: 25%;
}

*,
*::after,
*::before {
    box-sizing: inherit;
}

 

Now add on the index.ts

//Import the React and the control
import * as React from "react";
import * as ReactDOM from "react-dom";
import { ShowModal} from "./ModalControl"

//add a property on the main class
private _container: HTMLDivElement;

//change the init

public init(context: ComponentFramework.Context<IInputs>, notifyOutputChanged: () => void, state: ComponentFramework.Dictionary, container:HTMLDivElement)
	{
		this._container = container;
		// Add control initialization code
		
		
	}

//change the updateiew
public updateView(context: ComponentFramework.Context<IInputs>): void
	{
		// Add code to update control view
		ReactDOM.render(React.createElement(ShowModal, {}), this._container);
	}

Change on Destroy
public destroy(): void
	{
		// Add code to cleanup control if necessary
		ReactDOM.unmountComponentAtNode(this._container);
	}

 

Check if this could help you.

 

Here is the result of my code.

 

2020-06-23_152352.jpg

Hi Michael,

 

Thanks for your effort. Really appreciate it.

 

I tried your code and its working fine . But i can see that you have used 'react-dom' for modal component where as i have used 'react-modal' for mine code. Also you have not passed any props from index.ts to modalcontrol.tsx file where as i am passing one parameter value and i think thats where mine code is not working.

 

I am attaching my PCF Control files in the attachment as an zip. There are 4 files as mentioned below

a) index.ts

b) ABNControl.tsx

c) ABNModal.tsx

d) ABNModal.css

FYI , Index.ts file is importing ABNControl.tsx file which is rendering input textbox and then importing ABNModal.tsx file which is passing this input textbox value as props to ABNModal.tsx file.

ABNModal.tsx file is having one button on click on which it will open Modal popup and will show that input textbox value.

Thats what i want to achieve for now. 

 

Can you check my files and let me know where my code is wrong . 

 

Any help will be appreciated.

 

 

Thanks

 

Hi! As I mentioned early on the first reply. Remove this piece of code.

 

ReactModal.setAppElement('#app-root');

 

Because you don't have an HTML to set default <div> for the app, the <div> is given when the control is initialized. Like you create a react page project. When I remove this code works fine. 

 

If works, please mas as solution

Hi Michael,

 

Thanks for your help.

 

After removing that line of code , it was working fine in Dynamics 365 too.

 

Just to clarify , i added that piece of code it was giving me warning message in Console window.

Now i have removed it , still its giving that warning message as show in below screenshot

SumitThakran_0-1593057383639.png

 

can you suggest any code that will remove this warning.

 

Thanks

 

Helpful resources

Announcements
Power Apps News & Annoucements carousel

Power Apps News & Announcements

Keep up to date with current events and community announcements in the Power Apps community.

Community Call Conversations

Introducing the Community Calls Conversations

A great place where you can stay up to date with community calls and interact with the speakers.

Power Apps Community Blog Carousel

Power Apps Community Blog

Check out the latest Community Blog from the community!

Users online (2,162)