Error message in Angular 2: "__generator is not recognized"

I've been working on intercepting outgoing HTTP requests in Angular 2 in order to generate a token from the request body and attach it to the header of each post request. Below is the code snippet that I've implemented.

Initially, I encountered a runtime error stating:

"e.json() is not a function"

To address this error, I attempted to catch the exception and add a 'json' function if missing. However, this led to a new runtime error:

"message: __generator is not defined"
stack: "ReferenceError: __generator is not defined↵    at e.<anonymous>" 

In an effort to resolve this issue, I set "noEmitHelpers": false based on a suggestion from this question: async/await __generator is not defined

Despite this adjustment, the runtime error persists.

Any advice or assistance would be greatly appreciated.

declare var TextEncoder: any

import { Headers, Http, Request, RequestOptions, RequestOptionsArgs, Response, XHRBackend } from "@angular/http"

import { Injectable } from "@angular/core"

import { Observable } from "rxjs/Rx"

// operators

import "rxjs/add/operator/catch"

import "rxjs/add/observable/throw"

import "rxjs/add/operator/map"

import { fromPromise } from "rxjs/observable/fromPromise"

import { switchMap } from "rxjs/operators"

@Injectable()

export class DigestIntegrationInterceptor extends Http {    

    constructor(
        backend: XHRBackend,
        options: RequestOptions
    ) {
        super(backend, options)
    }
    
    
    request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
        return super.request(url, options);
    }                   

    post(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {                
        const timeStamp = new Date().getTime() + "";
        const tokenPromise = this.generateDigestHex(this.generateToken(body, timeStamp));                
        return fromPromise(tokenPromise).pipe(
            switchMap((token:string) => super.post(url, body, this.generateHeaders(token, timeStamp, options))),
            
            // add 'json' function to error if it's missing
            catchError(e => typeof e.json === 'function' ? Observable.throw(e): Observable.throw({ json: () => e })),
      
            // To check what the observable emits - for debugging purpose only
            tap({
               next: v => console.log('http interceptor next', v),
               error: e => console.log('http interceptor error', e),
            })
        );                
    }                         

    generateHeaders(token:string, timeStamp, options: RequestOptionsArgs){        
        if (options == null) {
            options = new RequestOptions();
        }
        if (options.headers == null) {
            options.headers = new Headers({ 'Content-Type': 'application/json' });
        }
        options.headers.append("X-TOKEN", token);
        options.headers.append("X-REQ-TS", timeStamp);

        return options;
    }

    generateToken(requestBody: any, timeStamp: string): string {
        return `X-${timeStamp}-${JSON.stringify(requestBody)}`;
    }    

    async generateDigestHex(message) {
        const msgUint8 = new TextEncoder().encode(message); 
        const hashBuffer = await crypto.subtle.digest("SHA-256", msgUint8); 
        const hashArray = Array.from(new Uint8Array(hashBuffer)); 
        const hashHex = hashArray
          .map((b) => b.toString(16)['padStart'](2, "0"))
          .join(""); 
        return hashHex;
    }
    
}

Answer №1

To access observable values in the correct way, you should modify your code as follows:

sendPostRequest(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {                
    const timeStamp = new Date().getTime() + "";
    const tokenPromise = this.generateDigestHex(this.generateToken(body, timeStamp));                
    return fromPromise(tokenPromise).pipe(switchMap((token:string) => {
      return super.post(url, body, this.generateHeaders(token, timeStamp, options));  
    }));          
}       

You need to switch to the post method once you have obtained the token value from the promise.

Answer №2

Once you have received the token from fromPromise(tokenPromise), switch to your post request.

return fromPromise(tokenPromise).pipe(
  // include 'json' function in case of error
  catchError(e => throwError({ json: () => Promise.resolve(e) })),
  switchMap((token:string) => 
    super.post(url, body, this.generateHeaders(token, timeStamp, options))
  ),
  
  // observe what your observable emits - for debugging purposes only
  tap({
    next: v => console.log('http interceptor next', v),
    error: e => console.log('http interceptor error', e),
  })
);  

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Integrating TypeScript into an established create-react-app project

Struggling to integrate TypeScript into an existing create-react-app? I've always added it at the beginning of a project using create-react-app my-app --scripts-version=react-scripts-ts, but that's not working this time. The only "solution" I co ...

Is there a way to retrieve a specific type from a union-based type by using a generic function in Typescript?

When working with my API, I have noticed a consistent pattern where it returns either a specific type or a TypeScript type called BadResult, as shown below: type Result1 = CreatedPersonResult | BadResult; type Result2 = CreatedRoleResult | BadResult; To s ...

Yes, it's not able to retrieve the value from headlessui combobox

I have encountered an issue while using the Headlessui combobox component in conjunction with Yup. Despite successfully storing the selected value in the selectedMemory state variable, Yup consistently generates a required error message. I seem to be overl ...

Stop Mat-chip from automatically inserting a row upon selection

I am working on preventing the automatic addition of a row by the mat-chip module after a single chip has been selected. Even though the max chip count is set to 1, the input remains enabled and adds a new row beneath it as if the user can still type more ...

Angular page startup triggers NPM, leading to a sudden crash

Our ASP.Net + Angular web pages running on the IIS server (built with .Net Core 2.1 and Angular5) have suddenly stopped functioning. An error message "AggregateException: One or more errors occurred. (One or more errors occurred. (The NPM script 'sta ...

AngularFire 2 dispatching email for password reset

I am looking to add a feature for resetting passwords or handling forgotten passwords using AngularFire2. It looks like the function sendPasswordResetEmail is either not available in AngularFire2 or the typings have not been updated yet. I tried accessing ...

Guide to retrieving specific information from a JSON file in an Angular application

Struggling with handling this JSON file [ [ { "category": "Bags", "productData": [ { "id": 1000, "name": "Tro ...

Resolving conflicts between AbortSignal in node_modules/@types/node/globals.d.ts and node_modules/typescript/lib/lib.dom.d.ts within an Angular project

An issue occurred in the file node_modules/@types/node/globals.d.ts at line 72. The error message is TS2403: Subsequent variable declarations must have the same type. Variable 'AbortSignal' should be of type '{ new (): AbortSignal; prototype ...

Uh oh! An issue occurred: Cannot access values of an undefined property (reading 'valueOf')

I am attempting to loop through the JSON data and extract the start time and end time keys. I have tried two different methods in my API code to achieve this. The console.log is not showing any errors, but the other loop method is causing an error to appea ...

Angular: Updating image tag to display asynchronous data

Utilizing Angular to retrieve user profile pictures from the backend, specifically Node.js/Express, has been mostly successful. However, there is one issue that I have encountered. The HTML displaying the profile picture does not re-render when the user up ...

How can I verify the value of a class variable in TypeScript by using a method?

I need a more concise method to inform TypeScript that my client has been initialized (no longer null). While I have achieved this functionality, the current implementation seems unnecessarily verbose. Here is how it currently looks: export abstract class ...

Issues with the functionality of Angular Firebase Authentication Service

I am currently working on setting up an authentication service in Angular that will integrate with Google Firebase for a Login form. However, I have encountered an issue where including the service in the constructor of my LoginComponent prevents me from a ...

Implementing Bootstrap 5 JS within an Angular 11 component TypeScript

I am currently working on a project that utilizes Angular 11 and we are aiming to integrate Bootstrap 5 native JS without relying on third-party libraries like ng-bootstrap, MDB, or ngx-bootstrap (jQuery is not being used as well). I understand that using ...

Steps for incorporating moment.js into an Angular 2 project

Having trouble importing moment.js into my angular2 application despite following various guides and solutions provided. Even though the package is present in my IDE (Visual Studio) and the moment.d.ts file is easily found, I keep encountering errors when ...

RxJs will only consider the initial occurrence of a specific type of value and ignore any subsequent occurrences until a different type of value is encountered

I'm faced with a situation where I need to extract the first occurrence of a specific value type, followed by the next unique value of a different type. Let's break it down with an example: of(1,1,1,1,2,3,4) .pipe( // some operators ) .subsc ...

Sending data between two distinct Angular components

In my angular project, I have two independent elements. One displays a list of license plates with two buttons for each plate: "View current position" and "View positions for the last 24 hours". Both buttons redirect to the same component which shows point ...

Issue with Pagination in Angular 7: Functioning Error

I am having trouble with my pagination setup. I am struggling to understand how to properly pass this.total = res.totalPage; from the Component to the Service so that it can count the pages correctly. Currently, it is only displaying one page as shown in t ...

How can I apply bold styling to my interpolation binding in Angular while working on my HTML code?

Below is the code snippet where I am attempting to highlight profile.userId: <p class="profile__last-login" *ngIf="profile.lastLoggedIn"> {{'intranet.profile.dashboard.lastLoggedIn' | messageBundle: profile.userId + ',' + (pr ...

Using Angular2's NgFor Directive in Components

I am faced with the challenge of converting a tree-like structure into a list by utilizing components and subcomponents in Angular 2. var data = [ {id:"1", children: [ {id:"2", children: [ {id: "3"}, {id: "3"}, {i ...

Encountering the error message "TypeError: this.http.post(...).map is not a function" after upgrading from Angular 5 to Angular

I encountered some issues with rxjs6 after upgrading from Angular 5 to Angular 6: TypeError: this.http.post(...).map is not a function error TS2339: Property 'map' does not exist on type 'Observable<Object>'. TypeError: rxjs__W ...