Skip to main content

Notifications

Community site session details

Community site session details

Session Id :
Power Apps - Power Apps Pro Dev & ISV
Answered

Issue with assigning variable as input to PCF control in Canvas App

(0) ShareShare
ReportReport
Posted on by 4

Hi all

 

I am loosing my mind with this issue - hope anyone can help me.

 

I have developed a React PCF control that is bound to a SingleLine.Text field. The control takes a string as input (parameter name is "value") and hides the 4 last characters of the string. The control has an associated toggle that can show/hide the last 4 characters of the string.

 

Here is the ControlManifest.Input.xml file:

 

 

 

<?xml version="1.0" encoding="utf-8" ?>
<manifest>
 <control 
 namespace="FieldAnonymizerComponent" 
	 constructor="FieldAnonymizerComponent"
		version="0.0.1" 
		display-name-key="FieldAnonymizerComponent" 
		description-key="FieldAnonymizerComponent description" 
		control-type="virtual" 
	>
 <external-service-usage enabled="false">
 </external-service-usage>
 <property name="value" display-name-key="value" description-key="value" of-type="SingleLine.Text" usage="bound" required="true" />
 <resources>
 <code path="index.ts" order="1"/>
 <platform-library name="React" version="16.8.6" />
 <platform-library name="Fluent" version="8.29.0" />
 </resources>
 </control>
</manifest>

 

 

 

 

Here is the index.ts file:

 

 

 

import { IInputs, IOutputs } from "./generated/ManifestTypes";
import AnonymizerComponent, { IAnonymizerComponentProps } from "./AnonymizerComponent";
import * as React from "react";

export class FieldAnonymizerComponent implements ComponentFramework.ReactControl<IInputs, IOutputs> {
 private _notifyOutputChanged: () => void;
 private _value: string;
 private _isReadOnly: boolean;
 private _refreshData: (value: string) => void;

 constructor() { }

 public init(
 context: ComponentFramework.Context<IInputs>,
 notifyOutputChanged: () => void,
 state: ComponentFramework.Dictionary
 void {
 this._value = context.parameters.value.raw ?? "";
 this._isReadOnly = context.mode.isControlDisabled;
 this._notifyOutputChanged = notifyOutputChanged;
 this._refreshData = this.refreshData.bind(this);
 }

 public updateView(context: ComponentFramework.Context<IInputs>): React.ReactElement {
 const props: IAnonymizerComponentProps = {
 value: this._value,
 isReadOnly: this._isReadOnly,
 refreshData: this._refreshData
 };

 return React.createElement(
 AnonymizerComponent, props
 );
 }

 public refreshData(value: string): void {
 this._value = value;
 this._notifyOutputChanged();
 }

 public getOutputs(): IOutputs {
 return {
 value: this._value
 };
 }

 public destroy(): void { }
}

 

 

 

 

Here is the React component:

 

 

 

import * as React from 'react';
import { Stack } from '@fluentui/react';
import { useState } from 'react';
import { provideFluentDesignSystem, fluentTextField, fluentSwitch } from '@fluentui/web-components';
import { provideReactWrapper } from '@microsoft/fast-react-wrapper';
import { Constants } from './../constants/constants';

const { wrap } = provideReactWrapper(React, provideFluentDesignSystem());
export const FluenTextField = wrap(fluentTextField());
export const FluentSwitch = wrap(fluentSwitch());

export interface IAnonymizerComponentProps {
 value?: string;
 isReadOnly: boolean;
 refreshData: (value: string) => void;
}

const AnonymizerComponent = (props: IAnonymizerComponentProps) => {
 const [isAnonymized, setIsAnonymized] = useState(true);
 const [value, setValue] = useState(props.value ?? "");

 return (
 <Stack horizontal>
 <FluenTextField
 value={isAnonymized ? anonymize(value) : value}
 style={{ width: "100px" }}
 onInput={(e: React.FormEvent<HTMLInputElement>) => updateValue(e)}
 readOnly={setIsReadOnly()}
 maxLength={Constants.MaxCprLength}
 />
 <Stack verticalAlign="end"> 
 <FluentSwitch 
 onClick={() => { isAnonymized ? setIsAnonymized(false) : setIsAnonymized(true) }}
 style={{ marginLeft: "10px", marginBottom: "6px" }}
 >
 <span slot="checked-message" style={{ paddingLeft: "7px" }}>{Constants.ToggleLabel}</span>
 <span slot="unchecked-message" style={{ paddingLeft: "7px" }}>{Constants.ToggleLabel}</span>
 </FluentSwitch>
 </Stack>
 </Stack> 
 )

 function updateValue(event: React.FormEvent<HTMLInputElement>): void {
 setValue(event.currentTarget.value);
 props.refreshData(event.currentTarget.value); 
 }

 function anonymize(value?: string): string {
 if (!value) return "";

 if (value.length == Constants.MaxCprLength) {
 return `${value.slice(Constants.CprSubSetMinValue, Constants.CprSubSetMaxValue)}${Constants.CprAnonymizedSuffix}`
 }

 return value;
 }

 function setIsReadOnly(): boolean {
 if (props.isReadOnly) return true;
 else return isAnonymized;
 }
}

export default AnonymizerComponent;

 

 

 

 

The PCF control works fine when added to a form in a model driven app.

 

Toggle off:

frederikkehlet_0-1710241396822.png

 

Toggle on:

frederikkehlet_1-1710241430609.png

 

However, when I try to add it to a Canvas App and apply the input for the "value" parameter using a variable, like so:

frederikkehlet_2-1710241554010.png

 

Nothing is shown in the control, even though I know that the variable contains the value "1111111111":

frederikkehlet_3-1710241647022.png

 

If I provide static value like so:

frederikkehlet_0-1710242371338.png

 

Then the value is displayed in the control:

frederikkehlet_1-1710242490791.png

 

 

I hope I have provided enough information and that someone can help me with this very strange issue. Thanks!

 

 

 

  • frederikkehlet Profile Picture
    4 on at
    Re: Issue with assigning variable as input to PCF control in Canvas App

    Thanks for the suggestion. I added it to my component and I also modified the updateView to set the value property using the context parameter that is provided to the function, instead of the private class variable. This fixed the issue.

  • Verified answer
    a33ik Profile Picture
    3,304 Most Valuable Professional on at
    Re: Issue with assigning variable as input to PCF control in Canvas App

    Hello,

    I believe issue with the behavior of your component is that when the value is changed externally - I mean after it was rendered for the first time (doesn't matter from Model Driven App or from Canvas App) you don't update the state inside your component. In order to do that you can use useEffect hook. Try the following code:

     

    React.useEffect(() => {
    setValue(props.value ?? "");
    }, [props.value]);

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

Announcing the Engage with the Community forum!

This forum is your space to connect, share, and grow!

🌸 Community Spring Festival 2025 Challenge Winners! 🌸

Congratulations to all our community participants!

Warren Belz – Community Spotlight

We are honored to recognize Warren Belz as our May 2025 Community…

Leaderboard > Power Apps - Power Apps Pro Dev & ISV

#1
WarrenBelz Profile Picture

WarrenBelz 87 Most Valuable Professional

#2
mmbr1606 Profile Picture

mmbr1606 71 Super User 2025 Season 1

#3
Michael E. Gernaey Profile Picture

Michael E. Gernaey 65 Super User 2025 Season 1

Overall leaderboard