1

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.

  • Yes you can use any of the 2 methods you have shared. Both are fine. Typescript is a language. The IAnnouncements currently has one property 'Value', declaring it separately could have been useful id there were more proeperties. This comes handy while declaring complex JavaScript objects. – mohd tahir Jul 27 '18 at 3:40
0

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);
      });
  • Thanks for your response Martijn - please allow me to ponder over this explanation and I will get back to mark the answer. Thanks again - really appreciated. – Amitabh Khan Bachhan Jul 18 '18 at 10:45
  • Would you perhaps be able to point out how I can examine this value property before writing any code? What I want to know is how to determine what properties the response object holds - value is one of them but I know that after reading the docs. How would I figure out what properties it holds using tool such as Fiddler? I tried checking the SPHttpClientResponse on Microsoft docs but there is no mention of the value property over there. I can just set a debugger after response.json() and see that it holds value - but how do I get the same property from Fiddler? – Amitabh Khan Bachhan Jul 18 '18 at 11:02
  • I always explore the api through Postman or the chrome debugger. And if I'm lazy, I copy paste the jsons to: json2ts.com and copy that model back into VSCode. – Oak3 Jul 18 '18 at 11:46
  • But would the value[] prop be shown in PostMan?- I have never seen it before while working with SharePoint Rest endpoints such as /_api/web/lists/getbytitle('test')/items on Fiddler or PostMan - it always returns under d:{} - am I missing something? – Amitabh Khan Bachhan Jul 18 '18 at 11:50
  • I'm not sure, but be aware of the fact that the spHttpClient defaults to odata4 and if you don't specifiy anything, you get odata3. That might explain the difference. You can check the headers of both calls to see what the differences are. – Oak3 Jul 18 '18 at 11:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.