问题
I'm trying to display messages on a feed using the following template called feed.component.html
<div class="feed">
<div *ngFor="let message of feed | async" class="message">
<app-messages [chatMessage]="message"></app-messages>
</div>
</div>
I keep getting the following error, and am unable to display the messages I send to the Firebase Database on my html chat page.
ERROR Error: InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe'
I've also got my feed.component.ts
file as follows:
import { Component, OnInit, OnChanges } from '@angular/core';
import { ChatService } from '../services/chat.service';
import { Observable } from 'rxjs/observable';
import { ChatMessage } from '../models/chat-message.model';
import { AngularFireList } from 'angularfire2/database';
@Component({
selector: 'app-feed',
templateUrl: './feed.component.html',
styleUrls: ['./feed.component.css']
})
export class FeedComponent implements OnInit, OnChanges {
feed: AngularFireList<ChatMessage[]>;
constructor(private chat: ChatService) { }
ngOnInit() {
console.log("feed init...")
this.feed = this.chat.getMessages();
}
ngOnChanges() {
this.feed = this.chat.getMessages();
}
}
I've also got my messages.components.ts
file below:
import { Component, OnInit, Input } from '@angular/core';
import { ChatService } from '../services/chat.service';
import { Observable } from 'rxjs/observable';
import { ChatMessage } from '../models/chat-message.model';
@Component({
selector: 'app-messages',
templateUrl: './messages.component.html',
styleUrls: ['./messages.component.css']
})
export class MessagesComponent implements OnInit {
@Input() chatMessage: ChatMessage;
userName: string;
userEmail: string;
messageContent: string;
timeStamp: Date = new Date();
constructor() { }
ngOnInit(chatMessage = this.chatMessage) {
this.messageContent = chatMessage.message;
this.timeStamp = chatMessage.timeSent;
this.userEmail = chatMessage.email;
this.userName = chatMessage.userName;
}
}
Can anyone please tell me what's wrong here and what I can do to fix it?
回答1:
What I did to solve the issue I was having was to change the following bit of code in the feed.component.ts file:
ngOnInit() {
console.log("feed init...")
this.feed = this.chat.getMessages().valueChanges(); // Added `valueChanges`
}
I believe it then gets the object from the Firebase Database, and then *ngFor iterates through the object to give me the content
, userNames
and timestamps
for each message.
If there's something wrong with this answer, please let me know as I'm still quite new to this.
Cheers.
---UPDATE---
Another way I found was to use a service, where I used Subject as an observable to store my response. This made it accessible to all the components, which was easier than worrying about parent-child relationships.
Service File
const response = Subject();
const response$ = response.asObservable();
async getData() {
await someApiCall.subscribe((element) => {
this.response.next(element);
})
}
Component.ts
const data = [];
getDataFromService {
this.data = async() => this.service.getDatata();
}
View
<div *ngFor="let i of data>
<p>{{i | async}}</p>
</div>
回答2:
AngularFireList
is to store the reference path, so that you can perform push()
, update()
and remove()
. You need to subscribe
to the list to get the values. For example
feedRef: AngularFireList<any>;
feeds: Observable<ChatMessage[]>;
ngOnInit() {
this.feedRef = this.db.list('chats');
this.feeds = this.feedRef.valueChanges();
}
Beacuse you are getting reference from chat service you need to do
feeds: Observable<ChatMessage[]>;
ngOnInit() {
this.feeds = this.chat.getMessages().valueChanges();
}
来源:https://stackoverflow.com/questions/49547793/display-firebase-data-on-html-page