TypeError: Вы указали недопустимый объект, где ожидался поток. Вы можете предоставить Observable, Promise, Array или Iterable

Я пытаюсь map из сервисного звонка, но получаю ошибку. Посмотрел подписаться не определяется в угловых 2? и он сказал, что для того, чтобы подписаться, нам нужно вернуться изнутри операторов. У меня также есть ответные заявления.

Вот мой код:

checkLogin(): Observable<boolean> {
    return this.service.getData()
        .map(
            response => {
                this.data = response;                            
                this.checkservice = true;
                return true;
            },
            error => {
                // debugger;
                this.router.navigate(['newpage']);
                console.log(error);
                return false;
            }
        )
        .catch(e => {
            return e;
        });
}

Журнал ошибок:

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

22 ответа

В моем случае ошибка произошла только во время тестов e2e. Это было вызвано throwError в моем AuthenticationInterceptor.

Я импортировал его из неправильного источника, потому что использовал функцию импорта WebStorm. Я использую RxJS 6.2.

Неправильно:

import { throwError } from 'rjxs/internal/observable/throwError';

Правильный:

import { throwError } from 'rjxs';

Вот полный код перехватчика:

import { Injectable } from '@angular/core';
import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class AuthenticationInterceptor implements HttpInterceptor {

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const reqWithCredentials = req.clone({withCredentials: true});
    return next.handle(reqWithCredentials)
     .pipe(
        catchError(error => {
          if (error.status === 401 || error.status === 403) {
            // handle error
          }
          return throwError(error);
        })
     );
  }
}

В вашем примере кода у вас есть map оператор получает два обратных вызова, когда он должен получать только один. Вы можете переместить свой код обработки ошибок в ваш обратный вызов catch.

checkLogin():Observable<boolean>{
    return this.service.getData()
                       .map(response => {  
                          this.data = response;                            
                          this.checkservice=true;
                          return true;
                       })
                       .catch(error => {
                          this.router.navigate(['newpage']);
                          console.log(error);
                          return Observable.throw(error);
                       })
   }

Вам также нужно будет импортировать catch а также throw операторы.

import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

РЕДАКТИРОВАТЬ: обратите внимание, что, возвращая Observable.throwв вашем обработчике перехвата вы на самом деле не поймаете ошибку - она ​​все равно появится на консоли.

Если ваша функция ожидает возврата логического значения, просто сделайте это:

  1. Импортировать:
import { Observable } from 'rxjs/Observable';
  1. затем
checkLogin(): Observable<boolean>{
    return this.service.getData()
           .map(response => {  
               this.data = response;                            
               this.checkservice=true;
               return true;
           })
           .catch(error => {
               this.router.navigate(['newpage']);
               console.log(error);
               return Observable.of(false);
           })
 }

Вы возвращаете Observable, где ваш код возвращает просто логическое значение. Так что вам нужно использовать, как показано ниже

.map(response => <boolean>response.json())

Если вы используете другой общий сервис checkservice в вашем случае вы можете просто использовать

this.service.getData().subscribe(data=>console.log(data));

Это сделает ваш checkLogin() функция с типом возврата как void

 checkLogin():void{
      this.service.getData()
            .map(response => {  
                           this.data = response;                            
                           this.checkservice=true;
             }).subscribe(data=>{ });

и вы можете использовать this.checkService проверить ваше состояние

У меня была эта ошибка, когда в проектах были разные версии RxJS. Внутренние проверки в RxJS не работают, потому что есть несколько разныхSymbol_observable. В конце концов эта функция выдает один раз вызванный из оператора сглаживания, напримерswitchMap.

Попробуйте импортировать наблюдаемый символ в некоторой точке входа.

// main index.ts
import 'symbol-observable';

У меня была такая же проблема, вызванная импортом внутренней версии takeUntil вместо операторов Изменить

import { takeUntil } from 'rxjs/internal/operators/takeUntil';

к

import { takeUntil } from 'rxjs/operators';

То же самое и с другими операторами

Я забыл вернуть другой наблюдаемый в pipe(switchMap(

this.dataService.getPerson(personId).pipe(
  switchMap(person => {
     //this.dataService.getCompany(person.companyId); // return missing
     return this.dataService.getCompany(person.companyId);
  })
)

Может быть вызвано случайной запятой (,) в RxJS pipe(...)

Компиляция не поймает эту дополнительную запятую в конце:

pipe(first(), map(result => ({ event: 'completed', result: result}),);

Становится "невидимым" undefined Оператор, который запутывает всю трубу и приводит к очень запутанному сообщению об ошибке - что в данном случае не имеет ничего общего с моей реальной логикой.

Подсказка для всех, кто сталкивается с этим. Это может произойти, когдаswitchMapне получает наблюдаемого возвращаемого значения (например, null). Просто добавьте кейс по умолчанию, чтобы он всегда возвращал наблюдаемое.

        switchMap((dateRange) => {
          if (dateRange === 'Last 24 hours') {
            return $observable1;
          }
          if (dateRange === 'Last 7 Days') {
            return $observable2;
          }
          if (dateRange === 'Last 30 Days') {
            return $observable3;
          }
          // This line will work for default cases
          return $observableElse;
        })

Я столкнулся с этой проблемой при попытке аутентификации пользователя с помощью веб-токена JSON. в моем случае это связано с перехватчиком аутентификации.

Отправка запроса на аутентификацию пользователя не должна предоставлять токен, так как он еще не существует.

Убедитесь, что ваш перехватчик включает это:

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

И что вы предоставляете {'No-Auth':'True'} на запрос вашего заголовка, как это:

  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});
  }

Я написал это, потому что приехал сюда в поисках той же ошибки, и это может пригодиться кому-то в будущем.

Я получаю ту же ошибку при попытке инициализировать переменную службы из ее конструктора, вызывая удаленный API через http.get и .subscribe()

После многих тестов, не понимая, в чем проблема, я наконец-то понял: у моего приложения была аутентификация и HttpInterceptor, и я пытался инициализировать сервис, вызывающий метод публичного API, используя http.get(...) без 'No-Auth Заголовки. Я добавил их как здесь, и проблема для меня решена:

getData() {
var reqHeader = new HttpHeaders({ 'Content-Type': 'application/x-www-urlencoded','No-Auth':'True' });    
return this.http.get(environment.urlApi.Literales, { headers: reqHeader });  
}

Что за головная боль:(

Вы также получите следующее сообщение об ошибке, если предоставите undefined или около того для оператора, который ожидает Observable, например. takeUntil.

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

В моем случае в Angular-5 сервисный файл не был импортирован, из которого я получал доступ к методу и подписывал данные. После импорта сервисного файла он работал нормально.

Эта ошибка произошла со мной, когда я использую перехватчик, вы должны сделать это в своем перехватчике

return next.handle(request).map(event => {
        if (event instanceof HttpResponse) {

        }
        return event;
    },
      catchError((error: HttpErrorResponse) => {
        if (error.status === 401 || error.status === 400) {
          // some logic

        }

Я не уверен, что это кому-то поможет, но в моем случае дальше по цепочке я использовал distinctUntilChanged и исключение внутри функции проявилось с этим сообщением об ошибке.

Эта ошибка случилась со мной @angular 7

Вы указали недопустимый объект там, где ожидался поток. Вы можете предоставить Observable, Promise, Array или Iterable.

Ошибка на самом деле не требует пояснений, в нем говорится somewhereв наблюдаемом я передаю недопустимый объект. В моем случае было много вызовов API, но все вызовы не выполнялись из-за неправильной конфигурации сервера. Я пытался использоватьmap, switchMap, или другой оператор rxjs, но операторы получают неопределенные объекты.

Так что дважды проверьте вводимые вами операторы rxjs.

Я также столкнулся с той же проблемой, когда вызывал метод внутри switchMap, по-видимому, я обнаружил, что если мы используем метод внутри switchMap, он должен возвращать наблюдаемый.

Я использовал канал для возврата наблюдаемого и отображения для выполнения операций внутри канала для вызова API, который я делал внутри метода, а не подписывался на него.

В моем случае я по ошибке импортировал Action в свой co mbEpics, а не Epic...

Убедитесь, что все функции в CombineEpics являются эпическими функциями

У меня была аналогичная ошибка при использовании RXJS в NESTJS.

      Error: TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable. +1ms

В моем случае я забыл вернуть Observable в switchMap. Это привело к тому, что в следующем коде оператора или клиента RXJS не было получено Observable.

Как только я вернул Observable в switchMap, ошибка исчезла.

Я получил ту же ошибку с другой проблемой, поэтому я отвечаю на свое решение здесь, чтобы люди, ищущие одно и то же, могли увидеть это.

Я следовал руководству по Supabase + Ionic Auth и хотел добавить проверку электронной почты (с помощью Angular Reactive Forms). Я определил свою группу проверки следующим образом:

        credentials = this.fb.nonNullable.group({
                  email: ['', Validators.required, Validators.email],
                  password: ['', Validators.required],
  })

И когда я добавил Validators.email, я внезапно получил ошибку, я никогда особо не смотрел Validators-lib, но когда я это сделал, я увидел, что вам нужно передать вторые проверки как массив. Так просто меняя['', Validators.required, Validators.email]к['', [Validators.required, Validators.email]]исправил проблему!

Рабочее решение:

        credentials = this.fb.nonNullable.group({
                  email: ['', [Validators.required, Validators.email]],
                  password: ['', Validators.required],
  })

У меня точно такое же сообщение об ошибке, когда я проводил свой модульный тест и выдавал наблюдаемое исключение после насмешки над моими услугами.

Я решил, передав точную функцию и формат внутри Observable.throw,

Актуальный код, который вызывает сервис и subscribe чтобы получить данные. заметить, что catch обращаться с 400 ошибка.

     this.search(event).catch((e: Response) => {
        if (e.status === 400) {
          console.log(e.json().message);
        } else if (e.url) {
          console.log('HTTP Error: ' + e.status + ' ' + e.statusText,
            'URL: ' + e.url, 'Info: ' + e.json().message));
        }
      }).finally(() => {
        this.loading = false;
      }).subscribe((bData) => {
        this.data = bData;
      });

Код внутри сервиса

  search() {
    return this.someService.getData(request)
       .do((r) => {
          this.someService.defaultHeaders.delete('skipAlert');
          return r;
        })
      .map((r) => {
          return r.businessObjectDataElements.length && r.businessObjectDataElements || null;
        });
  }

Модульное тестирование

Я издевался над SomeService и возвращал наблюдаемые данные и все в порядке, поскольку в нем есть все необходимые методы.

 someServiceApi = fixture.debugElement.injector.get(SomeService);
 spyOn(someServiceApi, 'getData').and.returnValue(Observable.of({}));

Приведенный выше код является окей, но когда я пытался проверить условие catch/error, передав Observable.throw({}) он показывал мне ошибку, как и ожидал Response Тип возврата из сервиса.

Так что ниже службы насмешливое возвращение давало мне эту ошибку.

someServiceApi.getData
  .and.returnValue(Observable.throw(new Response({status: 400, body: [], message: 'not found error'})));

Так что я исправил это, реплицировав точную ожидаемую функцию в моем возвращаемом объекте, передав Response введите значение.

someServiceApi.getData
  .and.returnValue(Observable.throw({status: 400, json: () => { return {message: 'not found error'}}, body: []}));
// see `json: () => { return {message: 'not found error'}}` inside return value

Что касается ошибки "Вы предоставили недопустимый объект там, где ожидался поток. Вы можете указать Observable, Promise, Array или Iterable".

Это могло произойти, если вы import { Observable } from 'rxjs' после (ниже) некоторого модуля / функции / чего угодно, который фактически использует его.

Решение: переместите этот импорт выше импорта этого модуля.

Другие вопросы по тегам