-
Notifications
You must be signed in to change notification settings - Fork 231
Response Parsers
Under the hood the library makes use of parser classes to handle converting the response object returned by fetch into the result. Each of the methods of the Queryable (get, post, patch, delete) also takes an optional parser argument.
The default parser, ODataDefaultParser, is used for all requests by default (except a few special cases). It will check the response for an error and then parse the response body as JSON. You can use it directly by importing it, but there is no need as it is the default. But if you wanted to it would look like the below and match the result you get by passing nothing.
import { ODataDefaultParser } from "sp-pnp-js";
pnp.sp.web.lists.getByTitle("test").items.get(new ODataDefaultParser()).then(result => {
console.log(result);
});
You can use the ODataRaw parser to return the raw results of requests, which can help with debugging. The ODataValue parser allows you to simple cast the returned value which can be useful if you are getting a simple value back or have created your own
import { ODataRaw, ODataValue } from "sp-pnp-js";
pnp.sp.web.lists.getByTitle("test").items.get(ODataRaw).then(result => {
console.log(result);
});
pnp.sp.web.lists.getByTitle("test").items.select("ItemCount").get(ODataValue<number>()).then(result => {
console.log(result);
});
There are also parsers to handle files but you shouldn't need to use them directly, these are: TextFileParser, BlobFileParser, BufferFileParser, JSONFileParser. See the Working with Files article for more details on manipulating files.
The final set of parsers are made to work with the getAs method. These allow you to merge the result data into one of the objects, such as list or an array of items. This allows you to merge the data results with your typed classes so you can make entities that match your list/item types or handle custom logic easily extending the library.
import { List, Item, ODataEntity, ODataEntityArray } from "sp-pnp-js";
class MyList extends List {
public Title: string;
}
class MyItem extends Item {
public Title: string;
}
pnp.sp.web.lists.getByTitle("test").getAs(ODataEntity(MyList)).then(result => {
// our result has a title property because it is cast as type "MyList"
console.log(result.Title);
// note the result is also a list instance
result.items.getAs(ODataEntityArray(MyItem)).then(items => {
// the return is cast as an array
console.log(items.length);
// the items are case as our type "MyItem"
console.log(items[0].Title);
});
});
After learning to use what is already included in the library the next step is writing your own parser. It is very likely you won't need to write a custom parser - but if you do this section describes the process.
The first step is implementing the ODataParser interface, which has a single method parse. The definition is below:
export interface ODataParser<U> {
parse(r: Response): Promise<U>;
}
When implementing the interface directly you are passed the Response object and must handle errors and parse the information to return in the parser. Below is an example to show a basic implementation - in this case returning the SharePoint health score from the header or throwing an Error.
import { ODataParser } from "sp-pnp-js";
class MyParser implements ODataParser<number> {
public parse(response: Response): Promise<number> {
return new Promise((resolve, reject) => {
if (response.ok) {
resolve(parseInt(response.headers.get("x-sharepointhealthscore")));
} else {
// there was some error
reject(new Error(response.statusText));
}
});
}
}
pnp.sp.site.get(new MyParser()).then(r => console.log(r));
You can use this technique to return values from the headers, combine them with other data, parse complex fields, or translate results into your custom objects while still making use of the framework.
Another option instead of implementing the interface from scratch is to extend the ODataParserBase class (or any of the others if that fits your needs). The below does the same thing as above, but makes use of the existing handleError method. You can also use the existing parseODataJSON method to parse the returned JSON.
import { ODataParserBase } from "sp-pnp-js";
class MyParser extends ODataParserBase<number> {
public parse(response: Response): Promise<number> {
return new Promise((resolve, reject) => {
if (this.handleError(response, reject)) {
resolve(parseInt(response.headers.get("x-sharepointhealthscore")));
}
});
}
}
pnp.sp.site.get(new MyParser()).then(r => console.log(r));
Sharing is caring!