Shantha Kumar T
Get all child terms from term group in SharePoint Taxonomy using PnP JS
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.
[code lang=”js”]
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);
});
});
});
});
}
[/code]
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.
[code lang=”js”]
//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>);
}
}
[/code]
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,
Its working for me in workbench.aspx. But when i deploy i getting into an error
Is there any method to get term URL ? I would like to associate pages in my SharePoint team site to a specific termset
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?
I am also getting the same issue on tbatch.execute
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
Hi, How to get and save Enterprise Keywords in SPFx
Hi Shantha,
What would Happen if the given user doesn’t have access to the term set ?
Thanks,
Suny Abraham