Working with Taxonomy is always a fun, because accessing terms from it requires us to write different way of code. SharePoint doesn’t provide the direct way of accessing the terms through REST API. We still require client.svc support for managing the taxonomy.
PnPjs library gives us the different methods and properties for managing the taxonomy, termgroup, termsets, termstores, terms and taxonomysessions.
We have to first install the below npm command to import taxonomy pnpjs modules in to our project,
npm install @pnp/logging @pnp/common @pnp/odata @pnp/sp @pnp/sp-taxonomy @pnp/sp-clientsvc –save
@pnp/sp-taxonomy and @pnp/sp-clientsvc modules are required in the project to call taxonomy related methods and properties.
//Returns the termstore based on the name. taxonomy.termStores.getByName("Taxonomy_kmABCdLRj1sbZy/jQhkZ+A==")
//Returns the termsets from the termgroup <termstore>.getTermGroupById("abcde73e-99f3-4112-89ed-431e98111a1z").termSets
//Returns the terms from the termset <termset>.terms
The below code returns the collection of the all terms across all the termsets from the retrieved termstore.
import { taxonomy, ITerm, ITermSet, ITermStore } from '@pnp/sp-taxonomy'; // // public async getTermsetWithChildren(): Promise<any[]> { let tms: any[] = []; return new Promise<any[]>((resolve, reject) => { const tbatch = taxonomy.createBatch(); return taxonomy.termStores.getByName("Taxonomy_kmRTKbLRj1sbZy/jQhkX+A==").get().then((resp1: ITermStore) => { return resp1.getTermGroupById("cfaeb73e-99f3-4112-89ed-431e98858e7f").termSets.get().then((resp2: ITermSet[]) => { resp2.forEach((ele: ITermSet) => { ele.terms.select('Name', 'Id').inBatch(tbatch).get().then((r3: ITerm[]) => { r3.forEach((t1: ITerm) => { let ip1 = { parent: ele['Name'], name: t1['Name'], id: t1['Id'].replace("/Guid(", "").replace(")/", "") }; tms.push(ip1); }); }); }); tbatch.execute().then(_r => { resolve(tms); }); }); }); }); }
we’ll see how to use the above code to fetch all terms across all termsets with a single taxonomy batch in SharePoint Framework webpart using pnpjs library.
Create a SharePoint Framework webpart project using
yo @microsoft/sharepoint
Then install pnpjs module to the spfx project. I have create a project name called “TaxonomyPopulator” and use the below code to show all terms in table in react based spfx webpart.
//TaxonomyPopulator.tsx import * as React from 'react'; import styles from './TaxonomyPopulator.module.scss'; import { ITaxonomyPopulatorProps } from './ITaxonomyPopulatorProps'; import { taxonomy, ITerm, ITermSet, ITermStore } from '@pnp/sp-taxonomy'; export interface IPTerm { parent?: string; id: string; name: string; } export interface ITaxonomyPopulatorState { terms: IPTerm[]; } export default class TaxonomyPopulator extends React.Component<ITaxonomyPopulatorProps, ITaxonomyPopulatorState> { constructor(props) { super(props); this.state = { terms: [] }; } public async getTermsetWithChildren(): Promise<IPTerm[]> { let tms: IPTerm[] = []; return new Promise<any[]>((resolve, reject) => { const tbatch = taxonomy.createBatch(); return taxonomy.termStores.getByName("Taxonomy_kmABCdLRj1sbZy/jQhkZ+A==").get().then((resp1: ITermStore) => { return resp1.getTermGroupById("abcde73e-99f3-4112-89ed-431e98111a1z").termSets.get().then((resp2: ITermSet[]) => { resp2.forEach((ele: ITermSet) => { ele.terms.select('Name', 'Id').inBatch(tbatch).get().then((resp3: ITerm[]) => { resp3.forEach((t: ITerm) => { let ip1 = { parent: ele['Name'], name: t['Name'], id: t['Id'].replace("/Guid(", "").replace(")/", "") }; tms.push(ip1); }); }); }); tbatch.execute().then(_r => { resolve(tms); }); }); }); }); } public componentDidMount() { this.getTermsetWithChildren().then((resp: IPTerm[]) => { console.log(resp); this.setState({ terms: resp }); }); } public render(): React.ReactElement<ITaxonomyPopulatorProps> { let termrow = this.state.terms.map((t: IPTerm) => { return <tr> <td>{t.name}</td><td>{t.id}</td><td>{t.parent}</td></tr>; }); return ( <div className={styles.taxonomyPopulator}> <div className={styles.container}> <div className={styles.row}> <div className={styles.column}> <span className={styles.title}>Terms from TermStore</span> </div> </div> <table> <thead><tr><th>Name</th><th>Id</th><th>Parent</th></tr></thead> <tbody>{termrow}</tbody> </table> </div> </div>); } }
The method getTermsetWithChildren() creates the the batch request and pushes all the terms request in to the tbatch = taxonomy.createBatch() by including in each request like below,
terms.select('Name', 'Id').inBatch(tbatch).get().then(())
After adding the above code to the SharePoint Framework project and we will get the below output,
October 28, 2019 at 8:28 PM
Its working for me in workbench.aspx. But when i deploy i getting into an error
December 29, 2019 at 5:54 PM
Is there any method to get term URL ? I would like to associate pages in my SharePoint team site to a specific termset
January 31, 2020 at 2:40 AM
Not able to compile the code… it underlines ‘execute’ tbatch.execute().then(r_ => {resolve(tms)} saying that Property ‘execute’ does not exist in type IObjectPathBatch. Can someone help please?
April 23, 2020 at 5:53 PM
I am also getting the same issue on tbatch.execute
April 23, 2020 at 5:58 PM
and in the npm install command it — not single –
npm install @pnp/logging @pnp/common @pnp/odata @pnp/sp @pnp/sp-taxonomy @pnp/sp-clientsvc –save
May 27, 2020 at 2:34 PM
Hi, How to get and save Enterprise Keywords in SPFx