Sharepoint SPFx CRUD operations on Lists using Angular

1) Introduction

This article is going to describe how set up the Sharepoint online in Office 365 and do CRUD operations on a List using Angular.

The source code for this is available at https://github.com/shahimsadakath/spfx-crud-sample

Let's get started.

2) Setting up the Sharepoint Online Account

You can visit Office 365 Developer program and register yourself for free developer subscription for one whole year. Remember to select "Sharepoint" as one of the products you want to develop.

Once you can registered you can use your credentials to login to Sharepoint development site in my case it is https://shadotnet.sharepoint.com.

3) Creating a List to perform CRUD operations

1. Click on settings icon on top right hand corner select "Add an app"








2. Select Custom List from the options











3. Give a name for your List. Remember this name will be used when we access the List from our SPFx webpart.










4. Then Click on Settings of the Created List












5. Add Columns as shown below by clicking "Create Column"












4) Integrate the Sharepoint List to SPFx Webpart

 1. Modify App.Settings.ts as shown below

export class AppSettings {    
     
    public static SP_URL = "{YOUR_SHAREPOINT_ONLINE_URL}";
    public static SP_LISTNAME = "{NAME_OF_SP_LIST}";
    public static GMAP_URL = "https://maps.google.com/maps/api/js?key={YOURKEY}";
    public static JQUERY_URL = "https://code.jquery.com/jquery-3.3.1.min.js";

 }

2. Create service SPFxService  as shownbelow

import { Injectable } from '@angular/core';
import { HttpClient,HttpParams,HttpHeaders } from '@angular/common/http'
import { AppSettings } from '../app.settings';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise'
import { observableToBeFn } from 'rxjs/testing/TestScheduler';
import {IRequestDigest,IListItemEntityType,IHttpPromiseCallbackArg} from '../app.common';




@Injectable()
export class SPFxService {
  public currentItem:any;
  listItemEntityTypeName: string = '';
  formDigestValue:string = '';
  

     constructor(private http: HttpClient) { 
       
   }

   public readItems(): Observable<any> {
   
    
    const headers = new HttpHeaders().set('accept','application/json;odata=nometadata');
    const requestOptions = {
      headers: headers
    };
    
    

    

    return this.http.get(`${AppSettings.SP_URL}/_api/web/lists/getbytitle('${AppSettings.SP_LISTNAME}')/items`, requestOptions
      );
    
    
   
  }

  private getRequestDigest() : Promise<IRequestDigest> {
    
let promise = new Promise<IRequestDigest>((resolve,reject)=>{

  const headers = new HttpHeaders().set('accept','application/json;odata=nometadata');
  const requestOptions = {
    headers: headers
  };

   this.http.post(AppSettings.SP_URL + '/_api/contextinfo','',requestOptions)
  .toPromise().then((res:IRequestDigest) => { this.formDigestValue = res.FormDigestValue; resolve(); });

});

   
      return promise;

   
  }

  public getListItemEntityTypeName() : Promise<IListItemEntityType> {
    
    
    let promise = new Promise<IListItemEntityType>((resolve,reject)=>{

      const headers = new HttpHeaders().set('accept','application/json;odata=nometadata');
      const requestOptions = {
        headers: headers
      };
      
      
   
     this.http.get(`${AppSettings.SP_URL}/_api/web/lists/getbytitle('${AppSettings.SP_LISTNAME}')?$select=ListItemEntityTypeFullName`
      ,requestOptions
    ).toPromise().then((res : IListItemEntityType)=>{ this.listItemEntityTypeName = res.ListItemEntityTypeFullName; resolve(); } );

    
    });

    return promise;
   
  }

public createItem(title: string, description: string, latitude: string,longitude:string) : Promise<any> {
    

   
  let promise = new Promise<IRequestDigest>((resolve,reject)=>{
    
    this.getListItemEntityTypeName()
    .then((res) => {
      
      return this.getRequestDigest();
    })    
      .then((res)  => {
        
        let headers = new HttpHeaders().set('accept','application/json;odata=nometadata');
        headers = headers.set('Content-type','application/json;odata=verbose');
        headers = headers.set('X-RequestDigest',this.formDigestValue);
    const requestOptions = {
      headers: headers
    };
  
        const body: string = JSON.stringify({
          '__metadata': {
            'type': this.listItemEntityTypeName
          },
          'Title': title,
          'Description' : description,
          'Latitude' : latitude,
          'Longitude':longitude
        });
        
       this.http.post(`${AppSettings.SP_URL}/_api/web/lists/getbytitle('${AppSettings.SP_LISTNAME}')/items`,  
        body,requestOptions).toPromise().then(res=>{ resolve();});
      });
    });

    return promise;
      
  }

  public readItem(id: number): Promise<any> {

    let promise = new Promise<IRequestDigest>((resolve,reject)=> {
    let headers = new HttpHeaders().set('accept','application/json');
    
const requestOptions = {
  headers: headers
};

    this.http.get(`${AppSettings.SP_URL}/_api/web/lists/getbytitle('${AppSettings.SP_LISTNAME}')/items(${id})`,requestOptions
     
    ).toPromise()
      .then((response) => {
        this.currentItem = response;
        
        resolve();
      }, (error: any): void => {
        reject(error);
      });
    });

    return promise;
  }

  public updateItem(id: number, title: string, description: string, latitude: string,longitude:string): Promise<any> {
    
    let promise = new Promise<IRequestDigest>((resolve,reject)=>{
    let listItemEntityTypeName: string = undefined;
    this.getListItemEntityTypeName()
      .then((res) => {
       
        return this.getRequestDigest();
      })
     
      .then((res) => {
        let headers = new HttpHeaders().set('accept','application/json;odata=nometadata');
        headers = headers.set('Content-type','application/json;odata=verbose');
        headers = headers.set('X-RequestDigest',this.formDigestValue);
        headers = headers.set('X-HTTP-Method', 'MERGE');
        headers = headers.set('IF-MATCH', this.currentItem["odata.etag"]);
    const requestOptions = {
      headers: headers
    };
  
        const body: string = JSON.stringify({
          '__metadata': {
            'type': this.listItemEntityTypeName
          },
          'Title': title,
          'Description' : description,
          'Latitude' : latitude,
          'Longitude':longitude
        });
        

       this.http.post(`${AppSettings.SP_URL}/_api/web/lists/getbytitle('${AppSettings.SP_LISTNAME}')/items(${id})?@target='${AppSettings.SP_URL}'`,  
        body,requestOptions).toPromise().then(res=>{ this.currentItem = null; resolve();});


       
        
      });
    });

    return promise;
  }

  public deleteItem(id:number): Promise<any> {
    
    
        let promise = new Promise<any>((resolve,reject)=>{
    this.getRequestDigest()
  
      .then((res) => {
        console.log(this.formDigestValue);
        let headers = new HttpHeaders().set('accept','application/json;odata=nometadata');
        headers = headers.set('Content-type','application/json;odata=verbose');
        headers = headers.set('X-RequestDigest',this.formDigestValue);
        headers = headers.set('X-HTTP-Method', 'DELETE');
        headers = headers.set('IF-MATCH', this.currentItem["odata.etag"]);
    const requestOptions = {
      headers: headers
    };

    const body: string = JSON.stringify({
      
      'Id': id
    });

        return this.http.post(`${AppSettings.SP_URL}/_api/web/lists/getbytitle('${AppSettings.SP_LISTNAME}')/items(${id})`,body,
        requestOptions).toPromise().then(res=>{ this.currentItem = null; resolve();});
      });
     
    });

    return promise;
  }
     


}

5) Demo

1. Read operation and Create operation 

Since no data available map shows empty












so we will click on Add New Location and add a Location as shown below











Now when we look at our Sharepoint List we can see that the Location has been successfully added.









2. Update Operation

We will click on Edit Button











Make some modifications as shown below.












Now when we look at our Sharepoint List we can see that the Location has been successfully updated.










3. Delete Operation

For the demo purpose I added another Location. 













Now when click on delete button we can see the Location as been successfully deleted














Comments