繁体   English   中英

找不到“object”类型的不同支持对象“[object Object]”。 NgFor 仅支持绑定到 Iterables,例如 Arrays。 ? 怎么解决?

[英]Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays. ? How solve it?

我有一个消息室应用程序,可以在使用同一个房间登录的用户之间为每个房间创建一个讨论聊天室,我面临这个错误:

找不到“object”类型的不同支持对象“[object Object]”。 NgFor 仅支持绑定到 Iterables,例如 Arrays。

我使用了 3 个功能:

  • getChatMessages() :从 Firestore 为同一个房间的用户获取所有聊天消息
  • getCurrentRoom():获取连接用户的房间
  • getUsers():返回所有同房间的用户

聊天服务.ts

import { Injectable } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/compat/auth';
import { AngularFirestore } from '@angular/fire/compat/firestore';
import { Observable } from 'rxjs';
import { Timestamp } from 'rxjs/internal/operators/timestamp';
import { switchMap,map, timestamp, filter } from 'rxjs/operators';
import { query, orderBy, limit, where } from "firebase/firestore";  
import firebase from 'firebase/compat/app';

 
export interface User {
  uid: string;
  email: string;
  displayName:string;
  username?:string;
  room?:string
}
 
export interface Message {
  createdAt: firebase.firestore.FieldValue;
  id: string;
  from: string;
  msg: string;
  fromName: string;
  myMsg: boolean;
}
 
@Injectable({
  providedIn: 'root'
})
export class ChatService {
  currentUser: User ;
  currentRoom:string="";
  updatedRoom:string="";
  constructor(private afAuth: AngularFireAuth, private afs: AngularFirestore) {
    this.afAuth.onAuthStateChanged((user) => {
      this.currentUser=user;
      console.log("current email"+this.currentUser.email);
           
  });
}
  async signup({ username,email, password,room }): Promise<any> {
     
    const credential = await this.afAuth.createUserWithEmailAndPassword(
      email,
      password
    );
 
    const uid = credential.user.uid;
 
    return this.afs.doc(
      `users/${uid}`
    ).set({
      uid,
      email: credential.user.email,
      username:username,
      room:room,
    })
  }
 
  signIn({ email, password }) {
    return this.afAuth.signInWithEmailAndPassword(email, password);
  }
 
  signOut(): Promise<void> {
    return this.afAuth.signOut();
  }

  addChatMessage(msg) {
    return this.afs.collection('messages').add({
      createdAt:firebase.firestore.FieldValue.serverTimestamp(),//firebase.default.firestore.Timestamp,
      msg: msg,
      from: this.currentUser.uid
    });
  }
   
   

   async getChatMessages() {
    let users = [];
    return   (await this.getUsers()).pipe(
      switchMap(res => {
        users = res;
        console.log("resssssss"+res);
        return this.afs.collection('messages', ref => ref.orderBy('createdAt','asc')).valueChanges({ idField: 'id' }) as Observable<Message[]>;
      }),

      map(messages => {
        console.log("messages"+messages);
        // Get the real name for each user
        for (let m of messages) {    
          m.fromName = this.getUserForMsg(m.from, users);
          m.myMsg = this.currentUser.uid === m.from;
        }      
        return messages
      })       
    )
  }
   
 


  public async getCurrentRoom() {
    await this.afs.collection('users', ref => ref.where("email", "==", this.currentUser.email)).get().toPromise()
        .then(snapshot => {
            snapshot.forEach(doc => {
              this.currentRoom=JSON.parse(JSON.stringify(doc.data())).room;
              console.log("current room" + this.currentRoom);
            });
        });
}
   
public async getUsers() {
  console.log("this room" + this.currentRoom);
  return this.afs.collection('users', ref => ref.where("room", "==", this.currentRoom)).valueChanges({
      idField: 'uid'
  }) as Observable < User[] > ;
}

  private getUserForMsg(msgFromId, users: User[]): string { 
    for (let usr of users) {
      if (usr.uid == msgFromId) {
        return usr.username ?? 'undefind';
      }
    }
    return 'Deleted';
  }


}

我的 chat.page.ts :

import { Component, OnInit, ViewChild } from '@angular/core';
import { IonContent } from '@ionic/angular';
import { Observable } from 'rxjs';
import { ChatService } from '../chat.service';
import { Router } from '@angular/router';
import { AngularFireStorage, AngularFireUploadTask } from '@angular/fire/compat/storage';
import { AngularFirestore, AngularFirestoreCollection } from '@angular/fire/compat/firestore';
import { finalize, tap } from 'rxjs/operators';
export interface FILE {
  name: string;
  filepath: string;
  size: number;
}
@Component({
  selector: 'app-chat',
  templateUrl: './chat.page.html',
  styleUrls: ['./chat.page.scss'],
})


export class ChatPage implements OnInit {
  ngFireUploadTask: AngularFireUploadTask;

  progressNum: Observable<number>;

  progressSnapshot: Observable<any>;

  fileUploadedPath: Observable<string>;
  room:any;
  files: Observable<FILE[]>;
ImgtoSend:any;
  FileName: string;
  FileSize: number;

  isImgUploading: boolean;
  isImgUploaded: boolean;

  private ngFirestoreCollection: AngularFirestoreCollection<FILE>;


  @ViewChild(IonContent) content: IonContent;
 
  messages:any=[];
  newMsg = '';
 
  constructor(private angularFirestore: AngularFirestore,
    private angularFireStorage: AngularFireStorage,private chatService: ChatService, private router: Router) { 
      this.isImgUploading = false;
      this.isImgUploaded = false;
      
      this.ngFirestoreCollection = angularFirestore.collection<FILE>('filesCollection');
      this.files = this.ngFirestoreCollection.valueChanges();

    }
 
  ngOnInit() {
    this.messages= this.chatService.getChatMessages();
  }
    
  sendMessage() {
    this.chatService.addChatMessage(this.newMsg).then(() => {
      this.newMsg = '';
      this.content.scrollToBottom();
    });
  }
 
  signOut() {
    this.chatService.signOut().then(() => {
      this.router.navigateByUrl('/login', { replaceUrl: true });
    });
  }








  fileUpload(event: FileList) {
      
    const file = event.item(0)

    if (file.type.split('/')[0] !== 'image') { 
      console.log('File type is not supported!')
      return;
    }

    this.isImgUploading = true;
    this.isImgUploaded = false;

    this.FileName = file.name;

    const fileStoragePath = `filesStorage/${new Date().getTime()}_${file.name}`;
    console.log("filestoragepath"+fileStoragePath);
    const imageRef = this.angularFireStorage.ref(fileStoragePath);
    console.log("image ref"+imageRef);
         
    this.ngFireUploadTask = this.angularFireStorage.upload(fileStoragePath, file);
    this.ImgtoSend=this.FileName;
    console.log("image to Send"+this.ImgtoSend);
    this.progressNum = this.ngFireUploadTask.percentageChanges();
    this.progressSnapshot = this.ngFireUploadTask.snapshotChanges().pipe(
      
      finalize(() => {
        this.fileUploadedPath = imageRef.getDownloadURL();
        console.log("uploaded path"+this.fileUploadedPath);

        this.fileUploadedPath.subscribe(resp=>{
          this.fileStorage({
            name: file.name,
            filepath: resp,
            size: this.FileSize
          });
          this.isImgUploading = false;
          this.isImgUploaded = true;
        },error => {
          console.log(error);
        })
      }),
      tap(snap => {
          this.FileSize = snap.totalBytes;
      })
    )
}


fileStorage(image: FILE) {
    const ImgId = this.angularFirestore.createId();
    
    this.ngFirestoreCollection.doc(ImgId).set(image).then(data => {
      console.log("data"+data);
    }).catch(error => {
      console.log(error);
    });
}  

 
}
enter code here

首先,您必须删除所有与问题无关的代码以帮助人们帮助您。

其次,问题很简单:

编译器在这里告诉您的是,Hey Mohammed Amir, *ngFor=""用于循环遍历Array of objects同时将object literal传递给它。

检查您在模板中绑定到*ngFor="let msg of [YourAssumedArrayFromEndpointResponse]"的属性的值,您会发现YourAssumedArrayFromEndpointResponse不是一个array 这就是编译器抱怨的原因

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM