Get all child terms from term group in SharePoint Taxonomy using PnP JS

How to access the taxonomy , termstore and terms and also here you can learn on how to fetch all the terms across termsets using pnp js library in SharePoint Framework project.

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,

 

Shantha Kumar
Shantha Kumar
Articles: 297

24,849 Comments

  1. Is there any method to get term URL ? I would like to associate pages in my SharePoint team site to a specific termset

  2. 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?

  3. 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

  4. Hi Shantha,

    What would Happen if the given user doesn’t have access to the term set ?

    Thanks,
    Suny Abraham

Comments are closed.