Reputation: 1278
I am trying to update messages in my ionic 4 app in realtime using angularfire2 and firebase realtime database. The code looks like below
On running it throws the exception Error: InvalidPipeArgument: '' for pipe 'AsyncPipe'
if i remove the word async then it shows up fine but when i post a new message from another instance then the entire data repeats.
html
<ion-list lines="full" style="background:transparent">
<ion-item style="padding-top:10px;" *ngFor="let msg of messages | async">
<ion-row style="width:100%;">
<ion-col size="3">
<ion-row>
<ion-col class="sg-reg-text">{{formatName(msg.name)}}</ion-col>
</ion-row>
<ion-row>
<ion-col style="padding:0;padding-left:8px" class="sg-tiny-text"><ion-icon name="time" color="light"></ion-icon> now</ion-col>
</ion-row>
</ion-col>
<ion-col style="border-bottom: 1px solid #7e7c8d;padding-bottom: 10px">
<ion-row>
<ion-col class="sg-reg-text">{{msg.message}}</ion-col>
</ion-row>
</ion-col>
</ion-row>
</ion-item>
</ion-list>
ts
messages:Post[]
refresh(){
this.messages = []
this.sgSvc.getMessages().subscribe(
(rsp:any) => {
for(let data of rsp){
console.log("hehe:" + JSON.stringify(data))
this.messages.push(new Post(data._name, data._message, data._uid))
}
}
)
}
ngOnInit() {
this.refresh()
}
svc.ts
private msgList: AngularFireList<Post>
getMessages(){
this.msgList = this.db.list<Post>('posts')
return this.msgList.snapshotChanges().pipe(
map(changes =>
changes.map(c => ({ key: c.payload.key, ...c.payload.val() }))
)
);
}
Upvotes: 1
Views: 342
Reputation: 38847
Try the following using the RxJS map()
operator to build the array of Post
objects rather than pushing the items to messages
each time in subscribe()
. You receive duplicate data when you remove the async
pipe with your current code because you are not re-initializing the array to an empty array. Either way you wouldn't use the async
pipe with an Array<T>
:
messages: Observable<Post[]>;
// ...
this.messages = this.sgSvc.getMessages().pipe(
map((messages: any) => messages.map(m => new Post(m._name, m._message, m._uid)));
);
You can also approach it without the async
pipe:
messages: Post[] = [];
// ...
this.sgSvc.getMessages().subscribe((messages: any) => {
this.messages = messages.map(m => new Post(m._name, m._message, m._uid));
});
Hopefully that helps!
Upvotes: 1