TypeError: You provided 'undefined' where a stream was expected

you provided 'undefined' where a stream was expected angular 6
you provided 'undefined' where a stream was expected angular 7
you provided 'undefined' where a stream was expected angular 8
you provided function where a stream was expected
error typeerror you provided function catcherroroperatorfunction source
you provided 'undefined' where a stream was expected switchmap
you provided 'undefined' where a stream was expected forkjoin
you provided 'undefined' where a stream was expected angular 5

I have an Ionic app that has a user provider with a signup() method:

doSignup() {
  // set login to same as email
  this.account.login = this.account.email;
  // Attempt to login in through our User service
  this.user.signup(this.account).subscribe((resp) => {
    this.navCtrl.push(MainPage);
  }, (err) => {
    //console.log('error in signup', err);
    // ^^ results in 'You provided 'undefined' where a stream was expected'
    //this.navCtrl.push(MainPage);

    // Unable to sign up
    let toast = this.toastCtrl.create({
      message: this.signupErrorString,
      duration: 3000,
      position: 'top'
    });
    toast.present();
  });
}

For some reason, this code never calls the success callback, only the error handler. When it does, it results in the error you see in the comment above.

My user.signup() method looks as follows:

signup(accountInfo: any) {
  return this.api.post('register', accountInfo).share();
}

My Api class looks as follows:

import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';

/**
 * Api is a generic REST Api handler. Set your API url first.
 */
@Injectable()
export class Api {
  public static API_URL: string = 'http://localhost:8080/api';

  constructor(public http: HttpClient) {
  }

  get(endpoint: string, params?: any, reqOpts?: any) {
    if (!reqOpts) {
      reqOpts = {
        params: new HttpParams()
      };
    }

    // Support easy query params for GET requests
    if (params) {
      reqOpts.params = new HttpParams();
      for (let k in params) {
        reqOpts.params.set(k, params[k]);
      }
    }

    return this.http.get(Api.API_URL + '/' + endpoint, reqOpts);
  }

  post(endpoint: string, body: any, reqOpts?: any) {
    return this.http.post(Api.API_URL + '/' + endpoint, body, reqOpts);
  }

  put(endpoint: string, body: any, reqOpts?: any) {
    return this.http.put(Api.API_URL + '/' + endpoint, body, reqOpts);
  }

  delete(endpoint: string, reqOpts?: any) {
    return this.http.delete(Api.API_URL + '/' + endpoint, reqOpts);
  }

  patch(endpoint: string, body: any, reqOpts?: any) {
    return this.http.put(Api.API_URL + '/' + endpoint, body, reqOpts);
  }
}

I tried removing share() from user.signup(), and returning Observable<any>, but that doesn't help.

I faced this issue when creating a new project using generator-jhipster-ionic (yo jhipster-ionic giving v3.1.2), following Matt Raible's (OP) Use Ionic for JHipster to Create Mobile Apps with OIDC Authentication blog article, but choosing JWT authentication instead of OIDC.

The origin of the issue was a mix of problems.

I had the issue when running a Ionic app with the livereload server, CORS issues happening and Angular HTTP returning the classic HTTP failure response for (unknown url): 0 Unknown Error, where 0 is the HTTP error code. However, in the current case the issue was hidden by bad error handling at the Observable level.

When you follow Angular's HttpClient #Error Details section advices, and add an Observable pipe with a catchError operator on the HTTP POST call, you can get the proper HTTP error details. In this case, instead of going down to the rxjs/util/subscribeToResult.js:71 (TS source #L80) TypeError: You provided 'undefined' where a stream was expected default error case, it goes to rx/util/subscribeToResult.js:23 (TS source #L34), and the error is handled properly in the piped method.

After following the Observable calls, I found that the current default authentication interceptor, as seen in this template src/providers/auth/auth-interceptor.ts catches HTTP error 401 and does nothing for the others, basically muting them and preventing their propagation.

TL;DR In the JWT case, the solution is to simply remove the src/providers/auth/auth-interceptor.ts .catch(...) block, allowing error propagation to login.service.ts, and in its this.authServerProvider.login(credentials).subscribe((data) => { ... }, (err) => { ... }) error callback.

I believe the issue and solution could be the same for your OIDC case, its signup method, and error callback.

[Edit] Even more since the same .catch code can be found in the starter example mentioned in the first post comments: ionic-jhipster-starter - auth-interceptor.ts#L31

TypeError: You provided 'undefined' where a stream was expected , I faced this issue when creating a new project using generator-jhipster-ionic (yo jhipster-ionic giving v3.1.2), following Matt Raible's (OP) Use  TypeError: You provided ‘undefined’ where a stream was expected. You can provide an Observable, Promise, Array, or Iterable. The code causing trouble! Here I am sharing snippets of code that were causing this issue. In the next section, I will share how it is resolved.

I did face this issue and in my case responseType suppose to be text (because of designed API end-point) rather than default json.

import { HttpClient } from '@angular/common/http';

Before:

getToken(tokenCommand) {
    return this.http.post(API_BASE_URL + 'user/token', tokenCommand);
}

After fixed:

getToken(tokenCommand) {
    return this.http.post(API_BASE_URL + 'user/token', tokenCommand
                                                     , { responseType: 'text' });
}

I think this error message is too general and it will be nice if it's developers could provide more detail/helpful error message. Thanks.

You provided 'undefined' where a stream was expected. You can , You can provide an Observable, Promise, Array, or Iterable. #3632. Closed. ajaykumarReddy opened this issue on May 3, 2018 · 5 comments. Closed  TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable

In my case I was returing with empty return:

if (...)
   return; // problem here

To fix, I returned the observed object:

if (...)
   return req.next();

You provided 'undefined' where a stream was expected · Issue , "ERROR TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.". TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable

Resolved here the right way :)

I have been facing this issue when trying to authenticate a user using JSON Web Token. in my case it's related to authentication interceptor.

Sending a request to authenticate a user doesn't have to provide a token since it doesn't exist yet.

Check that your interceptor include this:

if (req.headers.get('No-Auth') == "True")
            return next.handle(req.clone());

And that you provide {'No-Auth':'True'} to your header's request like this:

  authenticateUser(user): Observable<any> {
    const headers = new HttpHeaders({'No-Auth':'True'});
    headers.append('Content-Type', 'application/json');
    return this.httpClient.post(`${this.apiEndpoint}/auth/authenticate`, user, {headers: headers});
  }

Resolve! TypeError: You provided 'undefined' where a stream was , Resolve! TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable. TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

I had the same error and typical scenario was that I was returning different actions based on certain condition. But handling of one condition was missing and I was not returning anything under my effects. That's when this issue came up. It's always better to have a default return action to avoid such instances.

...mergeMap((res: FetchWorkflowStatusResponse) => {
   if(this){
      return action1
   } else if(that){
      return action2
   }
}

Now if some value other than this and that comes then there will not be any return statement and the error will be thrown.

IONIC 4 You provided 'undefined' where a stream was expected , ERROR TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable. TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

TypeError: You provided 'undefined' where a stream, However, when I send the request, I get this error: TypeError: You provided '​undefined' where a stream was expected. You can provide an Observable, Promise,  Learn the best of web development. Get the latest and greatest from MDN delivered straight to your inbox. The newsletter is offered in English only at the moment.

TypeError: You provided an invalid object where a stream - html, TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable - angular. You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.

TypeError: You provided an invalid object where a stream , In my case the error occurred only during e2e tests. It was caused by throwError in my AuthenticationInterceptor. I imported it from a wrong  Pasted into Resolve TypeError You provided undefined where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

Comments
  • Where are you call doSignup() ? Perhaps 'this' isn't available in that context.
  • It's called from <form (submit)="doSignup()"> in my signup.html: github.com/oktadeveloper/ionic-jhipster-starter/blob/master/src/…. signup.ts is here: github.com/oktadeveloper/ionic-jhipster-starter/blob/master/src/…
  • Thanks, Stéphane! This solved my issue. I did have to use Sid's workaround below as well since JHipster returns a 201 with "Created" in the body when registration succeeds.
  • I'm glad to hear it helped! On a side note, I don't understand why you use .share(), in the current case... It should mainly be used when you need real asynchronous behaviour, transferring ownership from the subscription caller to the data source, expecting multiple events to happen from it along its lifetime, and in order to use automatic ref-counted cleanup and source re-construction when subscribers come after all previous subscribers have left. With an HTTP call like here, I understand you may not want the HTTP call not to block, but asynchronous may seem overkill...
  • I understand you may want multiple simultaneous service subscribers and response caching with replay (like in What is the correct way to share the result of an Angular Http network call in RxJs 5?), but I'm just not sure about the current use cases (starter project and jhipster-ionic generator). Maybe nice features are to be expected/demonstrated in a future version?
  • thanks, although my problem was different, but removing catch block from the interceptor allowed me to reach the actual error.
  • In my case I simply wasn't returning an observable at all.. (~_~) ...I had the observable return commented out (-_-,) in my getStuff() method.
  • Thanks Sid! This helped me arrive at the solution. I had to do the following (because of TypeScript I suspect): signup(accountInfo: any) { return this.api.post('register', accountInfo, { responseType: 'text' as 'text' }).share(); }
  • Awesome! your solution helped me (Y). I also think the same "I think this error message is too general and it will be nice if it's developers could provide more detail/helpful error message"
  • You can use backticks (`) to mark inline code or triple backticks to mark code blocks