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

Notifications

Announcements

Community site session details

Community site session details

Session Id :
Power Platform Community / Forums / Power Apps / Issue with assigning v...
Power Apps
Unanswered

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!

 

 

 

I have the same question (0)
  • Verified answer
    a33ik Profile Picture
    3,306 Most Valuable Professional on at

    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]);
  • frederikkehlet Profile Picture
    4 on at

    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.

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

Forum hierarchy changes are complete!

In our never-ending quest to improve we are simplifying the forum hierarchy…

Ajay Kumar Gannamaneni – Community Spotlight

We are honored to recognize Ajay Kumar Gannamaneni as our Community Spotlight for December…

Leaderboard > Power Apps

#1
WarrenBelz Profile Picture

WarrenBelz 717 Most Valuable Professional

#2
Michael E. Gernaey Profile Picture

Michael E. Gernaey 329 Super User 2025 Season 2

#3
Power Platform 1919 Profile Picture

Power Platform 1919 268

Last 30 days Overall leaderboard