dennismuijs
dennismuijs

Reputation: 1215

http call not triggering in promise callback angular 2

In my angular 2 project I make this call to get some data:

this.http.getfromgraphql()
      .map((response: Response) => response.json())
      .subscribe(
        (data) => {
          console.log(data);
        });

This triggers the getfromgraphql function shown below, before I make that call though, I have to check if the access token is still valid in checkaccesstokenvalidity, there I set some variables and resolve the function.
the console logs 'in then' but my http post does not trigger.
Why is that?
Also, I am sure there is a better way to do this, but for the life of me I can't figure it out, a better solution is much appreciated

checkAccessTokenValidity() {
    let headers = new Headers();
    headers.append( 'Content-Type', 'application/x-www-form-urlencoded' );
    let options = new RequestOptions({ headers: headers });
    // if(!this.access_token) {
    return new Promise((resolve, reject) => {
      this.http.post(this.URL + 'oauth/token', this.authentication, options)
        .subscribe(function(response) {
            this.authObj = response.json();
            this.expirationDate = new Date();
            this.expirationDate.setSeconds(this.expirationDate.getSeconds() + this.authObj.expires_in);
            console.log(this.authObj, this.expirationDate);
          },
          error => console.log("Error: ", error),
          function() {
            console.log('resolving');
            resolve();
          });

    });
    // }
  }
  getfromgraphql() {
    let headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    // headers.append('Authorization', 'Bearer ' + this.access_token );
    let options = new RequestOptions({ headers: headers });

    this.checkAccessTokenValidity().then(function() {
      console.log('in then');
      //noinspection TypeScriptValidateTypes
      return this.http.post(this.URL + '/api/v1/graphql', this.query, options);
    });
  }

Upvotes: 1

Views: 1147

Answers (4)

CozyAzure
CozyAzure

Reputation: 8478

Point 1:

Do not use function(){} in any of your callbacks. Assuming you are using Typescript (or ES6 for that matter), you are not using lexical this. All of your this will have a reference to the inner scope. You will get lots of undefined. Use fat arrow notations ()=>{}.

Point 2:

Since you are already using Observables in all of your methods, continue to use them (reactive programming) and stay away from using Promise unless necessary.

In your getfromgraphql() method, simply use a flatMap(). It is the same as .then() in promise.

Also, in resolving the error, simply do a .catch() if needed. Observables will propagate the error to the highest caller.

checkAccessTokenValidity() {
    let headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    let options = new RequestOptions({headers: headers});
    return this.http.post(this.URL + 'oauth/token', this.authentication, options)
        .map(response => {
            this.authObj = response.json();
            this.expirationDate = new Date();
            this.expirationDate.setSeconds(this.expirationDate.getSeconds() + this.authObj.expires_in);
            console.log(this.authObj, this.expirationDate);
        })
        .catch(error=>{
            console.log(error);
            return Observable.empty();
        })
}

getfromgraphql() {
    let headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    // headers.append('Authorization', 'Bearer ' + this.access_token );
    let options = new RequestOptions({headers: headers});

    return this.checkAccessTokenValidity().flatMap(()=>{
        console.log('in then');
        //noinspection TypeScriptValidateTypes
        return this.http.post(this.URL + '/api/v1/graphql', this.query, options);
    })
}

Upvotes: 1

vaibhavmaster
vaibhavmaster

Reputation: 687

Use this

return this.http.post(this.heroesUrl, { name }, options)
       .toPromise()

or add a resolve() in your subscribe

 .subscribe(function(response) {
        this.authObj = response.json();
        this.expirationDate = new Date();
        this.expirationDate.setSeconds(this.expirationDate.getSeconds() + 
        this.authObj.expires_in);
        console.log(this.authObj, this.expirationDate);
        resolve();
      },

and instead of resolve in error you can use reject() in your error body

following plunker will help you https://embed.plnkr.co/?show=preview check for hero.service.promise.ts in app/toh folder

Upvotes: 0

Vamshi
Vamshi

Reputation: 9341

I dont understand why you are doing this.http.getfromgraphql() but for other code in reactive way its like this :

checkAccessTokenValidity() {
    let headers = new Headers();
    headers.append( 'Content-Type', 'application/x-www-form-urlencoded' );
    let options = new RequestOptions({ headers: headers });
    return this.http
               .post(this.URL + 'oauth/token', this.authentication, options)
               .map(response => {
                   this.authObj = response.json();
                   this.expirationDate
                      .setSeconds((new Date())
                      .getSeconds() + this.authObj.expires_in);
               });
      }

getfromgraphql() {
    let headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    // headers.append('Authorization', 'Bearer ' + this.access_token );
    let options = new RequestOptions({ headers: headers });

    this.checkAccessTokenValidity()
        .switchMap(token =>  this.http
               .post(this.URL + '/api/v1/graphql', this.query, options)   
 }

And the way you call this method is

someService.getfromgraphql()
           .subscribe(response=> {
// ....
});

Upvotes: 1

Fahad Nisar
Fahad Nisar

Reputation: 1733

Try replacing your post call with this :

return this.http.post(this.URL + '/api/v1/graphql', this.query, options).subscribe(() => {});

and see if it works now.

Upvotes: 0

Related Questions