Hi, all!
I'm working on a PCF component for Dynamics CRM based on suggestions from an API call. I'm using material-ui. My problem is that i cannot show all the values retrieved from a server. It's seems like "options" is not updated after the first fetch call. Below is the code from my component
import * as React from 'react'
import AutoComplete, { AutocompleteInputChangeReason } from '@material-ui/lab/Autocomplete'
import TextField from '@material-ui/core/TextField'
import { useState } from 'react';
export interface IDaDataControllerProps{
onValueChanged: (value?: any) => void;
onGetOptionLabel: (value?: any) => string
placeholder?: string
}
export const DaDataAddressComponent : React.FunctionComponent<IDaDataControllerProps> =
(props: IDaDataControllerProps) => {
const [options, setOptions] = useState([]);
return(
<AutoComplete
id = "combo-box-demo"
options = {options}
onInputChange = {(e: React.ChangeEvent<{}>, value: string, reason: AutocompleteInputChangeReason) => {
fetch('https://suggestions.dadata.ru/suggestions/api/4_1/rs/suggest/address',
{
method: "POST",
headers: {
'Authorization': 'Token 37bcc555cd055d433a5cb674500f7bc7f05bf474',
'Content-Type': 'application/json'
},
body: "{\"query\":\"" + value + "\"}"
}).then((response) => response.json().then((item) => setOptions(item.suggestions)))
}}
renderInput = {(params) => (
<TextField {...params} label= "Write any text"/>
)}
getOptionLabel = {(option) => props.onGetOptionLabel(option)}
onChange = {(event, value) => {props.onValueChanged(value)}}
/>
)
}
And here is the code of my index.ts file
import {IInputs, IOutputs} from "./generated/ManifestTypes";
import ReactDOM = require("react-dom");
import * as React from 'react'
import {DaDataAddressComponent} from "./DaDataAddressComponent"
export class addressDaDataAutoCompleteControl implements ComponentFramework.StandardControl<IInputs, IOutputs> {
private container: HTMLDivElement;
private notifyOutputChanged:() => void;
private addressValue?: string;
private postcodeValue?: string;
private cityValue?: string;
private streetValue?: string;
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.
* 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.
* notifyOutputChanged A callback method to alert the framework that the control has new outputs ready to be retrieved asynchronously.
* 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.
* container If a control is marked control-type='standard', it will receive an empty div element within which it can render its content.
* */
public init(context: ComponentFramework.Context<IInputs>, notifyOutputChanged: () => void, state: ComponentFramework.Dictionary, container:HTMLDivElement): void
{
this.container = container;
this.addressValue = context.parameters.address.raw ?? undefined;
this.postcodeValue = context.parameters.postcode.raw ?? undefined;
this.cityValue = context.parameters.city.raw ?? undefined;
this.notifyOutputChanged = notifyOutputChanged;
this.renderControl(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.
* 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
*/
public updateView(context: ComponentFramework.Context<IInputs>): void
{
this.addressValue = context.parameters.address.raw ?? "";
this.renderControl(context)
}
private renderControl(context: ComponentFramework.Context<IInputs>){
ReactDOM.render(
React.createElement(DaDataAddressComponent,{
placeholder: this.addressValue,
onValueChanged:(value?: any) => {
this.addressValue = value.value;
this.postcodeValue = value.data.postal_code;
this.cityValue = value.data.city;
this.streetValue = value.data.street_with_type
this.notifyOutputChanged();
},
onGetOptionLabel: (value?: any) => {return value.value}
}), this.container
)};
/**
* 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 {
address : this.addressValue,
postcode: this.postcodeValue,
city: this.cityValue,
street: this.streetValue
};
}
/**
* 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
{
}
}
When i input any text at first time the autocomplete shows all the retrieved suggestions(pic 1). But when i enter a more detalized name the component does not shows the retrieved values (pic 2).
So my question is what i'm doing wrong?
Thanks

Report
All responses (
Answers (