How To Use Loader/Spinner In SPFx

Introduction

Sometimes we want to apply some business logic like show loader/spinner while calling API until API responds. So for this, we will call a Graph API to get lists from the root site, and until API responds we will show Loader. We will use an Office UI fabric Spinner.
 
For more details refer to this.
  
So, in this article, we will see step-by-step implementation with SPFx webpart.

Implementation

Open a command prompt.

Move to the path where you want to create a project.

Create a project directory using,

md spfx-loader

Move to the above-created directory using,

cd spfx-loader

Now execute the below command to create an SPFx solution,

yo @microsoft/sharepoint

It will ask some questions, as shown below,

How To Use LoaderSpinner In SPFx

After a successful installation, we can open a project in any source code tool. Here, I am using the VS code, so I will execute the command,

code .

Now go to the src > webparts > webpart > components > I{webpartname}Props.ts file,

Here we will create a property for graph Client as below,

import { MSGraphClient } from "@microsoft/sp-http";

export interface ISpfxLoaderProps {
  description: string;
  graphClient: MSGraphClient;
}

Move to the {webpartname}.ts file. Here we will get the graph client and set it to the property,

import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import {
  IPropertyPaneConfiguration,
  PropertyPaneTextField
} from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';

import * as strings from 'SpfxLoaderWebPartStrings';
import SpfxLoader from './components/SpfxLoader';
import { ISpfxLoaderProps } from './components/ISpfxLoaderProps';
import { MSGraphClient } from '@microsoft/sp-http';

export interface ISpfxLoaderWebPartProps {
  description: string;
}

export default class SpfxLoaderWebPart extends BaseClientSideWebPart<ISpfxLoaderWebPartProps> {

  private graphClient: MSGraphClient;

  public onInit(): Promise<void> {
    return new Promise<void>((resolve: () => void, reject: (error: any) => void): void => {
      this.context.msGraphClientFactory
        .getClient()
        .then((client: MSGraphClient): void => {
          this.graphClient = client;
          resolve();
        }, err => reject(err));
    });
  }

  public render(): void {
    const element: React.ReactElement<ISpfxLoaderProps> = React.createElement(
      SpfxLoader,
      {
        description: this.properties.description,
        graphClient: this.graphClient,
      }
    );

    ReactDom.render(element, this.domElement);
  }

  protected onDispose(): void {
    ReactDom.unmountComponentAtNode(this.domElement);
  }

  protected get dataVersion(): Version {
    return Version.parse('1.0');
  }

  protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
    return {
      pages: [
        {
          header: {
            description: strings.PropertyPaneDescription
          },
          groups: [
            {
              groupName: strings.BasicGroupName,
              groupFields: [
                PropertyPaneTextField('description', {
                  label: strings.DescriptionFieldLabel
                })
              ]
            }
          ]
        }
      ]
    };
  }
}

Move to the {webpartname}.tsx file,

  • Create a State with loading and items properties
  • Create a constructor and initialize a state
  • Create a method getItems() and in this method, we will call a graph API to get lists from the root. And in this method before starting a call API we will set state loading to true and in the response and error function, we will set state loading to false.
  • And call getItems() in componentDidMount()

And in the render() method we will check if state loading is true then show Spinner and if the length of items is greater than 0 then we will show records.

import * as React from 'react';
import styles from './SpfxLoader.module.scss';
import { ISpfxLoaderProps } from './ISpfxLoaderProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { Spinner, SpinnerSize } from '@fluentui/react/lib/Spinner';

export interface ISpfxLoaderState {
  loading: boolean;
  items: any[];
}

export default class SpfxLoader extends React.Component<ISpfxLoaderProps, ISpfxLoaderState> {

  constructor(props: ISpfxLoaderProps) {
    super(props);
    this.state = {
      loading: false,
      items: []
    };
  }

  public componentDidMount() {
    this.getItems();
  }

  public getItems(){
    let graphURI: string = "/sites/root/lists";

    if (!this.props.graphClient) {
      return;
    }
    this.setState({
      loading: true,
    });

    this.props.graphClient
      .api(graphURI)
      .version("v1.0")
      .get((err: any, res: any): void => {
        if (err) {
          this.setState({
            loading: false
          });
          return;
        }
        if (res && res.value && res.value.length > 0) {
          console.log("res: ", res);
          this.setState({
            items: res.value,
            loading: false
          });
        }
        else {
          this.setState({
            loading: false
          });
        }
      });

  }

  public render(): React.ReactElement<ISpfxLoaderProps> {
    return (
      <div className={styles.spfxLoader}>
        <h2>{this.props.description}</h2>
        {
          this.state.loading &&
          <Spinner label="Loading items..." size={SpinnerSize.large} />
        }
        {
          this.state.items.length > 0 && this.state.items.map(m => <p>{m.name}</p>)
        }
      </div>
    );
  }
}

Output

How To Use LoaderSpinner In SPFx

Find the full source code here

Summary

In this article, we have seen how to use Spinner/loading in the SPFx webpart.
 
I hope this helps.
 
Sharing is caring!