1

I have the following code and as I havent worked with Promises a lot, then I am trying to understand, this question is more about an easy way to understand the code and not about a specific problem:

  private getRequestDigest(siteUrl: string): Promise<string> {
        const component: Reactwithmsgraphandsharepoint = this;
        return new Promise<string>((resolve, reject): void => {
          component.request(`${siteUrl}/_api/contextinfo`, 'POST').then((data: { FormDigestValue: string }): void => {
            resolve(data.FormDigestValue);
          }, (error: any): void => {
            reject(error);
          });
        });
       }


 private request<T>(url: string, method: string = 'GET', headers: any = null, data: any = null): Promise<T> {
    return new Promise<T>((resolve, reject): void => {
      const xhr: XMLHttpRequest = new XMLHttpRequest();
      xhr.onreadystatechange = function (): void {
        if (this.readyState === 4) {
          if (this.status === 200) {
            resolve(this.response as T);
          }
          else if (this.status >= 400) {
            reject({
              message: this.response['odata.error'].message.value,
              statusText: this.statusText,
              status: this.status
            });
          }
        }
      };

      xhr.open(method, url, true);
      if (headers === null) {
        xhr.setRequestHeader('Accept', 'application/json;odata=nometadata');
      }
      else {
        for (var header in headers) {
          if (headers.hasOwnProperty(header)) {
            xhr.setRequestHeader(header, headers[header]);
          }
        }
      }
      xhr.responseType = 'json';
      xhr.send(data);
    });
  }
  1. On the get request method, the request method is executed, but with 2 parameters, but the signature receives more, how does it know which parameters? by argument order?, doesnt it need all arguments to be passed?

  2. What is resolve and reject?

  3. I understand than code in then is executed after the web request is executed, however in the then I dont see a function at all, I see data: { FormDigestValue: string }): void => which is a syntax I dont understand.

  4. What is resolve(this.response as T); ? I come from C# and generics, so it looks like it can return anything?

  5. And finally, can I put anything on a reject?

reject({ message: this.response['odata.error'].message.value, statusText: this.statusText, status: this.status });

Luis Valencia
  • 32,619
  • 93
  • 286
  • 506
  • 1 - parameters method, headers and data have default values, so if you don't supply them, the defaults are used. 2 - resolve, reject are the callback functions you use to resolve or reject a promise, 3 - => is an arrow function, 4 - resolve is a Promise concept, 5 - yes, you can reject with anything you like – Jaromanda X Dec 14 '16 at 01:33
  • 1
    Avoid the [`Promise` constructor antipattern](http://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it) in `getRequestDigest`! – Bergi Dec 14 '16 at 02:42

1 Answers1

3

The code you posted is pretty hard on the eyes, and not practical at all. It's not a good place to start learning about promises.

A very good place to start instead is MDN (the Mozilla Dev Network). It has excellent documentation on Javascript topics, including the Promise.

Some quick answers:

  1. The request method takes 2 mandatory parameters, and the rest are optional, such as headers: any = null. This means that if headers (of type any) is not given as argument, it will default to null.

  2. Both functions return a Promise object, which represents a future value or error. resolve(value) is used to signal that the Promise successfully became a value, and reject(error) is used to signal that something went wrong.

  3. The code is executed after the request because it calls .then(onValue, onError) on the Promise returned from request. The functions passed to handle the 2 possible cases for the Promise are given as arguments:

    (data: { FormDigestValue: string }): void => { resolve(data.FormDigestValue) }
    (error: any): void => { reject(error) }
    

If the Promise returned from request is settled by resolve(data), this function will in turn resolve its own Promise to data.FormDigestValue.

If the Promise return from request is setteled by reject(error), this function will in turn reject its own Promise with the same error.

getRequestDigest is not very good code. As you'll learn by reading the MDN docs, Promise objects can be chained. The new Promise() constructor is harder to use, and not necessary in this case. It should instead read something like (skipping typescript here):

return component.request(url, method)
  .then(data => data.FormDigestValue)

.then will produce a new Promise, derived from the previous one (returned by component.request) to create the same result.

Did I mention to read the topic on MDN? Seriously, great resource.

salezica
  • 74,081
  • 25
  • 105
  • 166