Skip to content
This repository was archived by the owner on Aug 28, 2024. It is now read-only.

Extending with Custom Business Objects

Patrick Rodgers edited this page Mar 15, 2017 · 6 revisions

When developing an application you often have defined entities representing the data you are manipulating. In client side development these are often models or view models depending on what framework you are using - but generally define a set of data and the operations you can perform on that data. You can see a full example of this in the knockoutjs sample SPFx web part.

The sp-pnp-js library is designed to provide a base for you to build your custom objects and this article outlines that process. First let's take the simplest example, getting our list data back as a typed object instead of "any". To start we will define a class. You could use an interface here if you are only interested in retrieving data, but we will be adding to our class throughout this example so we have chosen a class.

class MyItem {
    public Id: number;
    public Title: string;
    public ProductNumber: string;
    public OrderDate: Date;
    public OrderAmount: number;   
}

And next we will retrieve items from a list using the getAs method. This is covered in more detail in the article on response parsers. Also a list is already created with the appropriate name and some sample data, this is covered later in this article.

import pnp from "sp-pnp-js";

// here we type our result as an array of MyItem instances. This uses our class like an interface
// and new instance of MyItem is not created, we are just using it for typing the results
pnp.sp.web.lists.getByTitle("ExtensibilityExample").items.getAs<MyItem[]>().then(items => {
    console.log(items[0].OrderAmount);
});

The next step is to update MyItem to extend the base Item class from the library. To do that we make two changes, add the extends declaration and add a constructor to match the base class's. To ensure your custom type will chain correctly inside the framework it is important that you include this constructor definition. We also need to import some supporting classes in addition to the pnp default.

import pnp,
{
    Queryable,
    Item,
    ODataEntityArray
} from "sp-pnp-js";

class MyItem extends Item {

    // you need to match the constructor of the base class
    constructor(baseUrl: string | Queryable, path?: string) {
        super(baseUrl, path)
    }

    public Id: number;
    public Title: string;
    public ProductNumber: string;
    public OrderDate: Date;
    public OrderAmount: number;
}

The next step is to update our call to get the items to use the ODataEntityArray parser which will merge the data coming back from SharePoint with a new instance of our MyItem class. Meaning we will have an object that has all of the methods of Item, properties of MyItem, and the ability to chain additional operations.

// here we type our result using the ODataEntityArray parser which will merge the data and object instance
// and type the result appropriately.
pnp.sp.web.lists.getByTitle("ExtensibilityExample").items.getAs(ODataEntityArray(MyItem)).then(items => {
    console.log(items[0].OrderAmount);
});

Clone this wiki locally