Question

I have a question on the following code. All of the code is taken after reading through various get started samples and then tweaked it a bit. I am trying to figure out how it works which is straight forward but I did have a question. Please refer to the following code:

    export interface IAnnouncement {
    Title: string;
    Modified: Date;  
    FieldValuesAsText: {
      Body: string;
      }
    AnnouncementPicture: {
      Description: string;
      Url: string;
    }
    }

    export interface IAnnouncements {
      value: IAnnouncement[];
    }

    const LISTCONSTANTS  = {
    LISTNAME: "CustomAnnouncements"
    }

    export default class CustomAnnouncementsWebPart extends BaseClientSideWebPart<ICustomAnnouncementsWebPartProps> {

      private retrieveListItems() : Promise<IAnnouncements> {
      return this.context.spHttpClient.get(this.context.pageContext.web.absoluteUrl + `/_api/web/lists/getbytitle('${LISTCONSTANTS.LISTNAME}')/items?$expand=fieldvaluesastext`, SPHttpClient.configurations.v1)
      .then((response:SPHttpClientResponse) => {
        return response.json();
      })
      }

      private renderAnnouncements(announcements: IAnnouncement[]) : void {
        let html: string = "";

        announcements.forEach((announcement: IAnnouncement) => {
           //html code removed for brevity
            html += <p  class="${styles.articlepara}"> ${announcement.FieldValuesAsText.Body} </p>               

        });
        const listContainer: Element = this.domElement.querySelector("#announcementsdiv");
        listContainer.innerHTML = html;

      }

      public render(): void {
        this.domElement.innerHTML = `<div id="announcementsdiv"></div>`;
        this.retrieveListItems().then((response) => {
            this.renderAnnouncements(response.value);
          });
      }

Why are we using two interfaces? Can we not just have the return type of retrieveListItems() to be IAnnouncement[] rather than Promise

So, for example, how are the following two method signatures different

    private retrieveListItems() : Promise<IAnnouncements>
    private retrieveListItems() : Promise<IAnnouncement[]>

The goal here is to understand the whole TypeScript and promises pattern as well as SharePoint Framework.

Thanks for reading folks.

Was it helpful?

Solution

You're interface has to represent the structure of the Json response returned by the api. That's why you have two interfaces:

IAnnouncements => the main response, with the metadata and the value property

IAnnouncment[] => an array of objects of type IAnnouncement that are stored in the value property of IAnnouncements.

Why you need to type it as a promise? That's what is returned by the reponse.json() call. Chain another then after that promise and you get the actual value without the promise. You do that in this step:

 this.retrieveListItems().then((response) => {
        this.renderAnnouncements(response.value);
      });
Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top