1
votes

I have tried many days on fixing this error over stackoverflow , Since i'm new to angular now I just need to ask from the community.I've been working on the JWT authentication

ERROR TypeError: Cannot read property 'subscribe' of undefined at RawMaterialComponent.loadRawMaterialsByCompany (raw-material.component.ts:774)

I have a service call as below in a component

    private loadRawMaterialsByCompany(callback: any) {
    let serviceSubscriptions =this.rawMaterialService.getRawMaterialsByCompany().subscribe(data => {
      this.rawMaterials = data;
      this.rawMaterialLoading = false;
    }, 
     error => this.handleError(error));
    }

and the service is as below

     getRawMaterialsByCompany() {
        const url = this.raw_material_api_endpoint + 'Company/' + this.company_id;
        return this.get(url);
      }

above service calls redirected to base service and it implements all http requests ie: get , post

What i want to do here is if the access token is expired i want to refresh the token. using a post request

     protected get(url: string) {
        if (this.isTokenExpired(localStorage.getItem('userToken'))) {

            this.getOriginalDataset(url).then((val)=>{

            this.getTokenfromService()
            return(val)
          });
        } else {
          return this.http.get(url)
            .map(this.extractRequests)
            .catch(this.handleError);
        }


    protected post(url: string, body: any) {
        if (url.includes("RefreshToken") || url.includes("Login") || url.includes("Logout")) {
          return this.http.post(url, body, { headers: this.getHeaders() })
            .map(this.extractRequests)
            .catch(this.handleError);
        }
        else {
            return this.http.post(url, body, { headers: this.getHeaders() })
              .map(this.extractRequests)
              .catch(this.handleError);

        }

      }

**per now i'm not going to refresh token for post requests

getOriginalDataset() method brings the requested data for the raw material component

getTokenfromService() method get the new access token and refresh token to store in local storage

    sendoriginalDataset(originalUrl):Promise<any>{
        return new Promise(resolve => {
        const dataSet= this.http.get(originalUrl, { headers: this.getHeaders() })
        .map(this.extractRequests)
        .catch(this.handleError);
        resolve(dataSet)
        });
      }

    async getTokenfromService() {

        const base64EncodedJwtAndRefreshToken = btoa(encodeURI(`${localStorage.getItem('userToken')}:${localStorage.getItem('refreshToken')}`));
        const url = this.login_api_endpoints + 'RefreshToken/';
        this.asyncResult = await this.post(url, JSON.stringify(base64EncodedJwtAndRefreshToken))
          .toPromise();
        console.log('First Promise resolved.')
        if (this.asyncResult !== null) {
          localStorage.setItem('userToken', this.asyncResult.jwtToken)
          localStorage.setItem('refreshToken', this.asyncResult.refreshToken)

        }

      }

both method runs properly but once getTokenfromService() executes the post request, console error pops as Cannot read property 'subscribe' of undefined

this happens for each and every http requests, above is a example . Small help is really appreciated !

2

2 Answers

2
votes

You cannot subscribe to a Promise. Change:

this.getOriginalDataset(url).then((val)=>{
this.getTokenfromService()
return(val)

To:

return from(this.getOriginalDataset(url)).pipe(
  tap(() => this.getTokenfromService())
)
1
votes

You have to use await to get the data

await this.getTokenfromService()

Please let me know if you still have any error