2

I have created a command set for managing products that are saved in a SP list. Each product's categories are saved on a metadata column (terms ) on that list.

If any user suddenly needs to edit an existing registered product, a ProductEditor react component will be rendered, after triggering the command set action. This component must show any term(s) that user may have already entered, for that sp list item.

For displaying the terms selection control, I'm using the TaxonomyPicker from PnP. Here is a part of my ProductEditor component.

import { TaxonomyPicker, IPickerTerms } from "@pnp/spfx-controls-react/lib/TaxonomyPicker";

public render(): React.ReactElement<IProductEditorProps> {
    return (
        <TaxonomyPicker
            termsetNameOrID="xxx"
            context={this.props.webContext as WebPartContext}
            onChange={categories => { this.setState({ category: categories[0] }); }} /> 
    );
}

The problem is when I need to set the initial values of the component with the ones retrieved from the list column. I can retrieve any term data from the term store with code below:

let term: ITermData & ITerm = await taxonomy
    .termStores.getByName('xxx')             // --> The name of the term store.
    .getTermSetById('yyy'),                  // --> The GUID of the term set.
    .getTermById('zzz');                     // --> The GUID of the original selected term.
    .get();

However, the variabele term is type of ITermData & ITerm but the TaxonomyPicker.initialValues property requests an IPickerTerms. How can I cast this to the correct type and back for the onChange method?

A product can only have one category, what means, the column will only contain 1 term.

The sp rest API data shows the below information regarding the taxonomy column on the list item:

<d:Category m:type="SP.Taxonomy.TaxonomyFieldValue">
    <d:Label>11</d:Label>
    <d:TermGuid>zzz</d:TermGuid>                     <!-- The GUID of the original selected term. -->
    <d:WssId m:type="Edm.Int32">22</d:WssId>
</d:Category>

PS: I'm creating different edit buttons because there're fields dependent from other fields. More info here: Replace default "new" action to custom created command SPFX.

  • Hey Pauwelyn! Did my answer help you on your issue? – Alberto S. Apr 19 at 18:05
  • @albertos the problem is that your answers comes a bit late. So I can't remember what the problem was. – H. Pauwelyn Apr 20 at 10:50
  • Yeah I know, I just found ur question yesterday and posted an answer, because I think it may be helpful for other developers. Basically, it tells how you can populate those metadata initialValues on your "TaxonomyPicker" component. It would be nice if u could set the question as solved it works for you :) – Alberto S. Apr 20 at 10:54
0

Not a big deal, just convert the termstore term to an object that follows the IPickerTerm type. Lets create a function like

async function convertTermPickerTerm (taxonomyTerm: ITermData & ITerm): Promise<IPickerTerm>  {
  let termset: ITermSetData & ITermSet = await taxonomyTerm.termSet.get();
  let termSet:string = termset.Id;
  const { Id: key, Name: name, PathOfTerm: path } = taxonomyTerm;
  return Promise.resolve( { key, name, path, termSet});
}

Then, after you have retrieved the details of the term already placed in your list column, just update your TaxonomyPicker component props:

import { TaxonomyPicker, IPickerTerms } from "@pnp/spfx-controls-react/lib/TaxonomyPicker";

public render(): React.ReactElement<IProductEditorProps> {
    return (
        <TaxonomyPicker
            termsetNameOrID="xxx"
            context={this.props.webContext as WebPartContext}
            initialValues = { [await convertTermPickerTerm (productTerm)] }
            onChange={categories => { this.setState({ category: categories[0] }); }} /> 
    );
}

That should work, good luck ;)

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.