Factory Pattern/Method in SharePoint Framework (SPFx)

Introduction 
 
In this blog, we will learn to perform Create, Read and Update operations using factory methods in the SharePoint Framework (SPFx).
 
A Factory Pattern or Factory Method Pattern defines an interface or abstract class for creating an object, but lets the subclasses decide which class to instantiate. In other words, subclasses are responsible to create the instance of the class.
 
The Advantage of Factory Design Pattern Factory Method Pattern is that it allows the sub-classes to choose the type of objects to create. It also promotes the loose-coupling by eliminating the need to bind application-specific classes into the code. That means the code interacts solely with the resultant interface or abstract class so that it will work with any classes that implement that interface or that extend the abstract class.
 
To start with, we require an interface or abstract class to define for our methods. In my example, I have defined my interface class as "IFactory.ts" as shown below. Method body is defined in "ListItemFactory.ts"
 
IFactory.ts 
 
Install @microsoft/sp-http to your .ts file as shown below.
  1. npm install --save @microsoft/sp-http
Import @microsoft/sp-http to your .ts file as shown below.
  1. import * as pnp from "@microsoft/sp-http";
  1. import { SPHttpClient, SPHttpClientResponse } from "@microsoft/sp-http";  
  2. export  interface IFactory {  
  3.     getItems(requester: SPHttpClient, siteUrl: string, listName: string, params: string, oListItemID: string): Promise<any[]>;  
  4.     addItems(requester: SPHttpClient, siteUrl: string, listName: string, body:string): Promise<any[]>;  
  5.     updateItems(requester: SPHttpClient, siteUrl: string, listName: string, oListItemID: string, body:string): Promise<any[]>;   
  6. }  
ListItemFactory.ts 
 
Install Jquery and @microsoft/sp-http to your .ts file as shown below.   
  1. npm install --save @microsoft/sp-http  
  2. npm install --save jquery  
Import @microsoft/sp-http and Jquery to your .ts file as shown below. 
  1. import * as pnp from "@microsoft/sp-http";  
  2. import $ from "jquery";   
  1. import { SPHttpClient, SPHttpClientResponse } from "@microsoft/sp-http";  
  2. import { IFactory } from "../factory/IFactory";  
  3. import $ from 'jquery';  
  4.   
  5. export class ListItemFactory implements IFactory {  
  6.       
  7.     /*Get items from sharepoint action item list*/  
  8.     public async getItems(requester: SPHttpClient, siteUrl: string, listName: string, params: string, oListItemID: string): Promise<any[]> {  
  9.         try {  
  10.             return requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items(${oListItemID})?${params}`,  
  11.                 SPHttpClient.configurations.v1,  
  12.                 {  
  13.                     headers: {  
  14.                         "Accept""application/json;odata=verbose",  
  15.                         "odata-version"""  
  16.                     }  
  17.                 })  
  18.                 .then((response: SPHttpClientResponse) => {  
  19.                     return response.json();  
  20.                 })  
  21.                 .then((json) => {  
  22.                     return json;  
  23.                 });  
  24.   
  25.         } catch (error) {  
  26.             console.log(`Error occured in getItems method in ListFactory.ts. Error message: ${error.message}`);  
  27.             throw error;  
  28.         }  
  29.     }  
  30.     /*Insert items to sharepoint action item list*/  
  31.     public addItems(requester: SPHttpClient, siteUrl: string, listName: string, body:string): Promise<any[]>{  
  32.         try{  
  33.             return requester.post(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items`,  
  34.                 SPHttpClient.configurations.v1,  
  35.                 {  
  36.                     headers: {  
  37.                         "Accept""application/json;odata=verbose",  
  38.                         'Content-type''application/json;odata=verbose',  
  39.                         "odata-version"""  
  40.                     },  
  41.                     body: body   
  42.                 })  
  43.                 .then((response: SPHttpClientResponse) => {  
  44.                     return response.json();  
  45.                 })  
  46.                 .then((json) => {                      
  47.                     return(json);                       
  48.                 });  
  49.       
  50.         }catch(error){  
  51.             console.log(`Error occured in addItems method in ListFactory.ts. Error message: ${error.message}`);  
  52.             throw error;  
  53.         }          
  54.     }  
  55.     /*Update items to sharepoint action item list*/  
  56.     public updateItems(requester: SPHttpClient, siteUrl: string, listName: string, oListItemID: string, body:string): Promise<any[]>{  
  57.         try {  
  58.             return requester.post(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items(${oListItemID})`,  
  59.                 SPHttpClient.configurations.v1,  
  60.                 {  
  61.                     headers: {    
  62.                         "Accept""application/json;odata=verbose",  
  63.                         'Content-type''application/json;odata=verbose',  
  64.                         "odata-version""",  
  65.                         'IF-MATCH''*',    
  66.                         'X-HTTP-Method''MERGE'   
  67.                       },    
  68.                       body: body   
  69.                 })  
  70.                 .then((response: SPHttpClientResponse): any => {  
  71.                     return true;  
  72.                 },(error: any): any => {    
  73.                     return false;  
  74.                 });;  
  75.         } catch (error) {  
  76.             console.log(`Error occured in updateItems method in ListFactory.ts. Error message: ${error.message}`);  
  77.             throw error;  
  78.         }  
  79.     }  
  80. }  
Usage : Import "ListItemFactory.ts" to your .tsx file as shown below.
  1. import { ListItemFactory} from "../ListItemFactory";  
Intitiate your class as shown below: 
  1. const factory: ListItemFactory = new ListItemFactory();  
Create - To Insert items to sharepoint list. 
 
Parameter : SPHttpClient,SiteURL, ListName and ListItemID. 
  1. /* create items using factory method pattern*/  
  2.         private insertItemsToSharePointList(): void {  
  3.             try {  
  4.             const body = this.loadNCMRBody();  
  5.             factory.addItems(this.props.spHttpClient, this.props.siteUrl, "SharePoint ListName", body)  
  6.                     .then((items: any[]) => {  
  7.                         if (items["d"].ID !== null) {  
  8.                             alert("Item Inserted successfully");  
  9.                         }  
  10.             });  
  11.             } catch (error) {  
  12.                 console.log(`Error occured in insertItemsToSharePointList method in Error message: ${error.message}`);  
  13.             }  
  14.         }  
  15.           
  16.         /** Load Item Body */  
  17.         private loadNCMRBody(button:string): string {  
  18.             try {  
  19.                 const body: string = JSON.stringify({  
  20.                     __metadata: { 'type'"SP.Data.<ListName>ListItem" },  
  21.                     Title:"Tested",  
  22.                     Description: "This is to test the description"                    
  23.                 });  
  24.                 return body;  
  25.             } catch (error) {  
  26.                 console.log(`Error occured in loadActionItemBody method in Process.tsx. Error message: ${error.message}`);  
  27.             }  
  28.         } 
Read - To Retrieve items to sharepoint list.
 
Parameter : SPHttpClient,SiteURL, ListName and ListItemID. 
  1. /* read items using factory method pattern and sets state accordingly*/  
  2.     private readItemsAndSetStatus(oListItemID) : void{  
  3.         factory.getItems(this.props.spHttpClient, this.props.siteUrl, <SharePoint ListName>, "$select=*", oListItemID)  
  4.             .then((items: any[]) => {                
  5.                this.setstate({Title:items["d"].Title,Description:items["d"].Description});  
  6.             });  
  7.     }
Update - To Update items in SharePoint list.
 
Parameter : SPHttpClient,SiteURL, ListName and ListItemID. 
  1. /* create items using factory method pattern*/  
  2. private updateItemsToSharePointList(): void {  
  3.     try {  
  4.     const body = this.loadNCMRBody();  
  5.     factory.updateItems(this.props.spHttpClient, this.props.siteUrl, "SharePoint ListName", body)  
  6.             .then((items: any) => {  
  7.                 if (items) {  
  8.                     alert("Item updated successfully");  
  9.                 }  
  10.     });  
  11.     } catch (error) {  
  12.         console.log(`Error occured in updateItemsToSharePointList method in Error message: ${error.message}`);  
  13.     }  
  14. }  
  15.   
  16. /** Load Item Body */  
  17. private loadNCMRBody(button:string): string {  
  18.     try {  
  19.         const body: string = JSON.stringify({  
  20.             __metadata: { 'type'"SP.Data.<ListName>ListItem" },  
  21.             Title:"Item Updated",  
  22.             Description: "This is to test the update method"                      
  23.         });  
  24.         return body;  
  25.     } catch (error) {  
  26.         console.log(`Error occured in loadActionItemBody method in Process.tsx. Error message: ${error.message}`);  
  27.     }  
  28. }
Please feel free to share your comments.
 
Hope this helps!!!!!