简体   繁体   English

错误类型错误:您在需要流的地方提供了“空”。 你可以提供一个 Observable、Promise、Array 或 Iterable

[英]ERROR TypeError: You provided 'null' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable

I searched everywhere for an answer but I couldn't get out this issue.我到处寻找答案,但我无法解决这个问题。 I found that many people are having this issues with Observables in Angular but usually it was just a syntax error.我发现很多人在使用 Angular 中的 Observables 时遇到了这个问题,但通常这只是一个语法错误。 I tried many things (I will list them below) but I'm confused.我尝试了很多东西(我将在下面列出它们)但我很困惑。 I don't know why it does like this.我不知道为什么它会这样。

ERROR:错误:

ERROR TypeError: You provided 'null' where a stream was expected.错误类型错误:您在需要流的地方提供了“空”。 You can provide an Observable, Promise, Array, or Iterable.您可以提供 Observable、Promise、Array 或 Iterable。

That's not a functionality error.这不是功能错误。 In fact, it works perfectly with my expectations, but it throws an error to the console.事实上,它完全符合我的期望,但它会向控制台抛出一个错误。

EXPECTATION:期待:
It's just an ngIf directive that manages the view of a menu content.它只是一个管理菜单内容视图的 ngIf 指令。 If the user is logged, it should view certain menu-items (for ex. 'My profile', etc...), if not, it should only see 'Login' and 'Signup' buttons.如果用户已登录,它应该查看某些菜单项(例如“我的个人资料”等...),否则,它应该只看到“登录”和“注册”按钮。 It actually works this kind of system, but I receive a console error.它实际上适用于这种系统,但我收到一个控制台错误。

WHAT I TRIED:我试过的:
Googling around I tried many things.谷歌搜索我尝试了很多东西。 The one listed below are only few of them, but at some point I was just trying without knowing really how to solve the problem.下面列出的只是其中的一小部分,但在某些时候,我只是在尝试而不知道如何真正解决问题。

In the first try (which I will not list here because it was pretty long), I tried to switchMap the angular fire auth state to get the logged status, then I setted this.appUser$ to this.userService.get(user.uid), to return user data from the database.在第一次尝试中(我不会在这里列出,因为它很长),我尝试 switchMap angular fire auth state 以获取记录状态,然后我将 this.appUser$ 设置为 this.userService.get(user.uid ),从数据库返回用户数据。 This will be the final result, but after getting the error I simplified by a lot the code to find out what can be the issue with that, hoping that it was easier.这将是最终结果,但在得到错误后,我简化了很多代码以找出可能存在的问题,希望它更容易。 In fact, I didn't solved anything in 3 days of tries.事实上,我在 3 天的尝试中没有解决任何问题。

  1. navbar.component.html导航栏.component.html

<mat-menu #userMenu="matMenu">
  <ng-template matMenuContent >
    <div class="menuContent" *ngIf="(appUser$ | async) as user; else notLoggedMenuitems">
      <div mat-menu-item>
        <div class="row no-gutters ml-2 mr-2">
          <div class="col-auto"><img [src]="user.photoURL" class="user-profile-img" alt="Profile image"></div>
          <div class="col"><p class="mat-body-strong mb-0 ml-3" style="line-height: 350%;"><b>{{ user.displayName }}</b></p></div>
        </div>
      </div>
      <mat-divider class="mt-2"></mat-divider>
      <div mat-menu-item>...</div>
      <div mat-menu-item>...</div>
      <mat-divider></mat-divider>
      <div mat-menu-item (click)="logout()">Logout</div>
    </div>

    <ng-template #notLoggedMenuitems>
      <div mat-menu-item routerLink="/auth/login">Login</div>
      <div mat-menu-item routerLink="/auth/signup">Signup</div>
    </ng-template>
  </ng-template>
</mat-menu>
  1. navbar.component.ts导航栏.component.ts

export class NavbarComponent implements OnInit {

  appUser$: Observable<firebase.User>;

  constructor(private auth: AngularFireAuth) {
    this.appUser$ = this.auth.user;
  }

  ngOnInit(): any {
  }

  logout(): void {
    this.auth.signOut();
  }

}
  1. navbar.component.html导航栏.component.html
    I changed the ngIf directive to the one below, removing the else block.我将 ngIf 指令更改为下面的指令,删除 else 块。 I tried even with other operators like " ! " and so on, but nothing changed...我什至尝试使用“!”等其他运算符,但没有任何改变......

*ngIf="(appUser$ | async)"
  1. navbar.component.ts导航栏.component.ts

export class NavbarComponent implements OnInit {

  appUser$: Observable<firebase.User> = this.auth.user;

  constructor(private auth: AngularFireAuth) {}

  ngOnInit(): any {
  }

  logout(): void {
    this.auth.signOut();
  }

}

CONCLUSION:结论:
How can I do this?我怎样才能做到这一点? I don't know why typescript throws this error.我不知道为什么打字稿会抛出这个错误。

UPDATE 1:更新1:
Updated navbar.component.html更新了 navbar.component.html

<mat-menu #userMenu="matMenu">
  <ng-template matMenuContent >
    <div class="menuContent" *ngIf="(appUser$ | async) as user; else notLoggedMenuitems">
      <div mat-menu-item>
        <div class="row no-gutters ml-2 mr-2">
          <div class="col-auto"><img [src]="user.details.imgUrl" class="user-profile-img" alt="Profile image"></div>
          <div class="col"><p class="mat-body-strong mb-0 ml-3" style="line-height: 350%;"><b>{{ user.name }}</b></p></div>
        </div>
      </div>
      <mat-divider class="mt-2"></mat-divider>
      <ng-container *ngIf="user.roles.admin">
        <div mat-menu-item><mat-icon>local_bar</mat-icon>Manage Drinks</div>
          <div mat-menu-item><mat-icon>note_add</mat-icon>Add Drinks</div>
          <mat-divider></mat-divider>
      </ng-container>
      <div mat-menu-item><mat-icon>settings</mat-icon>My Profile</div>
      <div mat-menu-item><mat-icon>wine_bar</mat-icon>My Drinks</div>
      <div mat-menu-item><mat-icon>favorite</mat-icon>Wishlist</div>
      <mat-divider></mat-divider>
      <div mat-menu-item (click)="logout()">Logout</div>
    </div>

    <ng-template #notLoggedMenuitems>
      <div mat-menu-item routerLink="/auth/login">Login</div>
      <div mat-menu-item routerLink="/auth/signup">Signup</div>
    </ng-template>
  </ng-template>
</mat-menu>

Updated navbar.component.ts更新了 navbar.component.ts

import { Component, OnInit } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import { Observable } from 'rxjs';

import { AuthenticationService } from './../../../auth/authentication/authentication.service';
import { User } from './../../../auth/authentication/models/user.model';



@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.scss']
})
export class NavbarComponent implements OnInit {

  appUser$: Observable<User>;

  constructor(private authService: AuthenticationService, private auth: AngularFireAuth) {
  }

  ngOnInit(): any {
    this.appUser$ = this.authService.user$;
    this.appUser$.subscribe(res => console.log('in app user: ', res));
  }

  logout(): void {
    this.auth.signOut();
  }

}

Updated authentication.service.ts更新了 authentication.service.ts

private initUser(): void {
  this.user$ = this.afAuth.authState.pipe(
    switchMap(user => {
      if (user) {
        return this.db.doc$<User>(`users/${user.uid}`);
      } else {
        return undefined;
      }
    })
  );
}

UPDATE 2:更新 2:
Updated authentication.service.ts更新了 authentication.service.ts

private initUser(): void {
  this.user$ = this.afAuth.authState.pipe(
    switchMap(user => {
      if (user) {
        return this.db.doc$<User>(`users/${user.uid}`);
      } else {
        return new Observable<User>();
      }
    })
  );
}

Now I don't see the error anymore.现在我看不到错误了。 But the user image doesn't shows well... I don't know if that's a good method to do things though.但是用户图像不能很好地显示......我不知道这是否是一种做事的好方法。

I think you almost got it.我想你几乎明白了。
What is not correct is the way you handle your user$ in your service.不正确的是您在服务中处理 user$ 的方式。 You should always return an observable in a switchMap operator.您应该始终在 switchMap 运算符中返回一个 observable。
To handle the case where there's no user login, you can use of() .要处理没有用户登录的情况,您可以使用of() It's an observable that emits the value passed in param and complete right after that.它是一个 observable,它发出传入 param 的值并在此之后完成。
Regarding the database your using, are you using firestore or the realtime database ?关于您使用的数据库,您使用的是 firestore 还是实时数据库? To request your data, in both cases, you need to end your call with valueChanges to return an observable.要请求您的数据,在这两种情况下,您都需要使用 valueChanges 结束您的调用以返回一个 observable。
I asume you are using firestore since you called the doc method:我假设您正在使用 firestore,因为您调用了 doc 方法:

private initUser(): void {
  this.user$ = this.afAuth.authState.pipe(
    switchMap(user => {
      if (user) {
        // return an observable<User>
        return this.db.doc<User>(`users/${user.uid}`).valueChanges();
      } else {
        return of(null);
      }
    })
  );
}

Try this, it should work.试试这个,它应该可以工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 类型错误:您提供了一个预期流的无效对象。 你可以提供一个 Observable、Promise、Array 或 Iterable - TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable 类型错误:您在需要流的地方提供了“未定义”。 你可以提供一个 Observable、Promise、Array 或 Iterable - TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable 错误类型错误:您在需要流的地方提供了“未定义”。 您可以在 Angular 服务中提供 Observable、Promise、Array 或 Iterable - ERROR TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable in Angular Services TypeError:您在需要 stream 的地方提供了“未定义”。 部署angular时可以提供Observable、Promise、Array或Iterable - TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable when deploying angular Angular5:TypeError:您提供了&#39;undefined&#39;,其中包含一个流。 您可以提供Observable,Promise,Array或Iterable - Angular5 : TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable TypeError:您在预期 stream 的地方提供了“未定义”。 您可以提供 Observable、Promise、Array 或 Iterable。 在<jasmine></jasmine> - TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable. at <Jasmine> @ngrx / effects给出了TypeError:你提供了&#39;undefined&#39;来预期流。 您可以提供Observable,Promise,Array或Iterable - @ngrx/effects gives TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable 您提供了“未定义”的预期流。 您可以提供一个Observable,Promise,Array或Iterable - You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable Angular:您在需要流的地方提供了一个无效的对象。 你可以提供一个 Observable、Promise、Array 或 Iterable - Angular: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable xplat您提供了一个无效的对象,该对象应在其中流。 您可以提供一个Observable,Promise,Array或Iterable - xplat You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM