Error in Angular 4: Unexpected 'undefined' provided instead of a stream

I encountered an issue while attempting to make a HTTP Post request. The error message I received is as follows:

auth.service.ts?c694:156 Something went wrong requesting a new password, error message: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

The first Http request preceding this one works perfectly fine.

This is the code snippet of my component calling the service:

requestNewPassword(formInput: NgForm) {
     if(formInput.controls['email'].value != '')
      this.authService.getApplicationAccessToken()
      .mergeMap((response: IAuthAppResponse) => this.authService.requestNewPassword(formInput, response.access_token))
      .subscribe(response => {
        // Content removed for simplicity
      })
    }

Below is the service method generating the aforementioned error:

public requestNewPassword(formData: NgForm, applicationAccessToken: string): Observable<any> {
      let headers = new HttpHeaders({
        'Authorization':'Bearer ' + applicationAccessToken
      });
      let email: string = formData.controls['email'].value;
      const body = {
        email: email
      };

      console.log('requestNewPassword call header: ' + headers.get('Authorization'));
      console.log('Email: ' + body.email);

      return this.http.post(this.baseUrl + '/api/user/password/forgot', body, {headers}).do(response => {
        console.log("New password was successfully sent to the e-mail adress");
      }).catch((error: HttpErrorResponse) => {
        console.log('Something went wrong requesting a new password, error message: ' + error.message);
        return Observable.throw(error);
      })
    }

Whenever I submit an email through the form, triggering the requestNewPassword method in the component, I encounter the previously mentioned error from the service.

The logged header and email values are correct, so it seems that the data being provided is not the issue.

As I am unsure how to debug this further, I decided to seek assistance by posting this question here.

Thank you in advance!

Update

In an effort to pinpoint the problem, I have streamlined the code in my component by eliminating the chaining of the two HTTP requests and only executing the second one which is causing trouble.

requestNewPassword(formInput: NgForm) {
      if(formInput.controls['email'].value != '')
      this.authService.requestNewPassword(formInput, "")
       .subscribe(response => {
         // Content removed for simplicity
       })
     }

A complete stack trace is now displayed:

ERROR TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable...
    at Object.subscribeToResult (subscribeToResult.js?c011:74)
    ...
    at HTMLFormElement.globalZoneAwareCallback (zone.js?fad3:1566)

Since there is mention of html in the error message, I will also include the corresponding html code:

<form class="custom_form" #requestNewPasswordForm="ngForm" (ngSubmit)="requestNewPassword(requestNewPasswordForm)">
    <label>E-mail</label>
    <input class="custom_input" type="email" class="inputfield form-control" ngModel name="email">
    <button class="btn btn-default" type="submit">
      Send
    </button>
</form>

Answer №1

Through persistent effort, I successfully identified and resolved the issue at hand. The root of the problem lay with an authorization interceptor that was intercepting all requests to insert an Authorization header with a user access token.

The specific call I was making did not necessitate a user access token, but rather an application access token (for authenticating as an application for public HTTP requests such as registration and password resets). To solve this, I decided to chain together the calls to retrieve the application access token and request the forgotten password. Subsequently, I passed the obtained application access token to the forgot password method in my service and set it in the Authorization header there. The code for this process functioned correctly. However, the issue arose from my modification of the interceptor to check for the presence of an Authorization header. If present, the interceptor would do nothing – this oversight led to the bug.

Instead of taking no action, I should have simply returned the request so it could proceed without alterations to the header.

Therefore, rather than:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        if(request.headers.get('Authorization') == null) {
          //Code to add Authorization header
          return next.handle(requestWithAuthHeader)
        }
}

I had to implement the following:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        if(request.headers.get('Authorization') == null) {
          //Code to add Authorization header
          return next.handle(requestWithAuthHeader)
        } else {
          return next.handle(request);
        }
}

Otherwise, the request would be intercepted and never executed since it wasn't being returned by the interceptor. The method in my component was subscribed to the service method's result, expecting an observable. However, nothing was returned due to the interception of the request and the inaction of the interceptor upon detecting an existing Authorization header (already set within the service).

This clarifies why I encountered the error stating that undefined was provided when an observable stream was expected on the subscribe line within my component's method.

Answer №2

Dealing with a similar issue, I discovered the root of the problem lay in an HTTP interceptor. My predicament stemmed from having an automatic deserialization function set up for all responses following a specific API endpoint pattern. This setup caused any responses that were not instances of HTTPResponse to vanish into thin air. To remedy this, I included an else statement that simply returned the response untouched if it did not match the HTTPResponse instance:

@Injectable()
export class DeserializerInterceptor implements HttpInterceptor {
  public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).map(
      event => {
        if (event instanceof HttpResponse) {
          let response = event as HttpResponse<any>;
          // ... code for deserializing response object
          return response;
        } else {
          return event; // ... introducing this else statement resolved the `undefined` error.
        }
      }
    );
  }
}

(Omitted error handling details for better understanding.)

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

Using `reduce` in TypeScript, you can organize an array of objects based on a shared property

Here is an example of an array: [ { id: '1', task: 'Grocery shopping', isImportant: true }, { id: '2', task: 'Meeting', isImportant: false }, { id: '3', task: &apos ...

Learn how to restrict input to only specific characters in an input box using Angular2 and validations

Is it possible to restrict user input in an input box to only specific characters such as '7' and '8'? I tried adding validations with attributes like type="number", min="7" and max="8", but even then other keys can be inserted before v ...

Replicate the process of transferring table rows to the clipboard, but exclusively copying the contents

Currently, I am attempting to copy a paginated table to my clipboard by referring to this guide: Select a complete table with Javascript (to be copied to clipboard). However, the issue lies in the fact that it only copies the data from the first page. In ...

Tips for expanding the functionality of the d3-selection module using TypeScript

I am currently working on a project that involves TypeScript and d3. I have already installed 'd3' and '@types/d3', and my use of d3 looks like this: import * as d3 from 'd3'; const x = d3.scaleLinear ... Everything was goin ...

What is the best way to reload a React/TypeScript page after submitting a POST request?

I am working on a custom plugin for Backstage that interacts with Argo CD via API calls. To retrieve application information, I make a GET request to the following endpoint: https://argocd.acme.com/api/v1/applications/${app-name} If the synchronizati ...

Here's how you can retrieve URL parameters in NextJs, such as `userid/:this_is_a_param`

I'm struggling to retrieve URL parameters using Next.js. I normally do this with Express by getting a :param from the URL like this: users/:userid/ console.log(req.params.userid) All I've been able to do is get the "userid" from the URL like thi ...

Encountered an error stating "Cannot find module node:fs" while using eslint-typescript-import, eslint-import-resolver-typescript,

Challenge My attempt to configure path alias in my TypeScript project was met with failure. Two errors arose during the execution of npm start: Module not found: Error: Can't resolve '~/App' in 'D:\work\workbench\templa ...

Node Package Manager (NPM): Easily Importing Files from a Package

Is there a way to customize the file import paths within a package? I am working with a UI kit package for our internal project and after building with Webpack, my project structure looks like this: - dist - components - index.d.ts - index.js Prior ...

The VueJS function is not defined

Looking for a way to fetch data from graphql in my vue project and store it in a variable. The function is asynchronous and the value of rawID needs to be awaited. However, there is a possibility that it could result in undefined, causing an error in the ...

Troubleshooting: Socket.io integration in Angular is not functioning within a .then() statement

Upon running this code snippet in a component: const videoholder = <HTMLDivElement>( document.querySelector('#videoholder') ); const myPeer = new Peer(this.userid, { host: '/', ...

Tips for maintaining a healthy balance of tasks in libuv during IO operations

Utilizing Typescript and libuv for IO operations is crucial. In my current situation, I am generating a fingerprint hash of a particular file. Let's say the input file size is approximately 1TB. To obtain the file's fingerprint, one method involv ...

Angular 2 form validation allowing submission to continue despite tag errors

Here is the code snippet provided: <form #theForm="ngForm" novalidate> <div *ngIf="pickUpAddress.cannotVerify"> <div class="form-group"> <sh-manual-address [(ngModel)]="pickUpAddress" #manualAddress="ngModel" [address]="pickU ...

The encryption and decryption feature is not functioning properly within the client-server application

We are currently experiencing issues with the encryption-decryption of data. On the server-side, we have decryption Java code that looks like this: public static String decrypt(byte[] data, PrivateKey base64PrivateKey) throws NoSuchPaddingException, NoSuc ...

Encountering a reference type error when using drag and drop with NextJS and react-dnd

When using react-dnd version 16 with TypeScript in Next.js, the refs within the return array of the useDrag and useDrop hooks are not compatible with LegacyRef. Interestingly, other platforms like Vite.Js handle this type assignment correctly. The same co ...

Is it possible to retrieve the signature for every method within a class?

Let's consider a scenario where we have a class defined as follows: class Actions { static FooAction = 'foo' as const; someAction1() { return { type: Actions.FooAction, payload: {a: 1, b:2} }} static BarAction = &apos ...

Discover the method to determine the total count of days in a given week number

I am developing a gantt chart feature that allows users to select a start date and an end date. The gantt chart should display the week numbers in accordance with the ISO standard. However, I have encountered two situations where either the start week numb ...

Using NgModel with a custom element

I am currently using a basic component within my form as shown below: <app-slider [min]="field.min" [max]="field.max" [value]="field.min"></app-slider> This component consists of the following code: HTML: <input #mySlider class="s ...

Angular: Determining when a form has returned to its original state

My current task involves working with a reactive form that comes with default values. I need to figure out how to prevent the user from saving changes until they have modified something, and then revert back to the initial state. Although I can subscribe ...

Discover the outcome of clicking on an object (mock tests)

I am just starting out with React and I'm unsure about when to use mocking. For instance, within the 'ListItem' component, there is a 'click me' button that reveals a dropdown for 'cameras'. Should I focus on testing what ...

Tips for bringing in a feature that is available in JavaScript but missing in TypeScript definitions and troubleshooting any resulting errors

Utilizing react-native-keyboard-aware-scroll-view, the library has the following exports in their code: export { listenToKeyboardEvents, KeyboardAwareFlatList, KeyboardAwareSectionList, KeyboardAwareScrollView } However, the index.d.ts file does n ...