Angular и Ionic 4 для прослушивания данных в реальном времени. Ошибка: InvalidPipeArgument: '' для канала 'AsyncPipe'

Я пытаюсь обновить сообщения в своем приложении ionic 4 в реальном времени, используя angularfire2 и базу данных firebase realtime. Код выглядит следующим образом

При запуске выдает ошибку исключения: InvalidPipeArgument: '' для канала 'AsyncPipe'

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

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>&nbsp;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() }))
   )
  );
  }

person Moblize IT    schedule 09.01.2019    source источник
comment
Это потому, что messages не Observable<T>, это просто Array<T>, к которому вы подталкиваете объекты. Вам не нужно использовать async pipe с messages.   -  person Alexander Staroselsky    schedule 09.01.2019
comment
Если я этого не сделаю, я перейду к другой проблеме, о которой я упоминал   -  person Moblize IT    schedule 09.01.2019


Ответы (1)


Попробуйте выполнить следующее, используя оператор RxJS map() для построения массива из Post объектов, вместо того, чтобы перемещать элементы в messages каждый раз в subscribe(). Вы получаете повторяющиеся данные, когда удаляете канал async с помощью текущего кода, потому что вы не повторно инициализируете массив пустым массивом. В любом случае вы не будете использовать канал async с 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)));
);

Вы также можете подойти к нему без async трубы:

messages: Post[] = [];

// ...

this.sgSvc.getMessages().subscribe((messages: any) => {
  this.messages = messages.map(m => new Post(m._name, m._message, m._uid));
});

Надеюсь, это поможет!

person Alexander Staroselsky    schedule 09.01.2019
comment
Теперь это приводит меня к другой ошибке: Ошибка: не удается найти другой поддерживающий объект '[object Object]' типа 'object'. NgFor поддерживает привязку только к Iterables, таким как Arrays. - person Moblize IT; 09.01.2019
comment
Вы можете подтвердить, что messages набирается как Observable<Post[]>? Также можете ли вы подтвердить, возможно, с помощью временной подписки, что оператор карты генерирует массив? - person Alexander Staroselsky; 09.01.2019
comment
Можете ли вы выйти из системы, которую генерирует оператор карты? Можете ли вы подтвердить, что он создает массив для Post объектов? Или в HTML просто используйте канал json вместо ngFor только для устранения неполадок. - person Alexander Staroselsky; 09.01.2019
comment
извините, как мне это напечатать? размещение console.log внутри карты не работает (messages: any) = ›. Также обратите внимание, что мой код svc.ts все тот же - person Moblize IT; 09.01.2019
comment
В вашем HTML просто сделайте {{messages | async | json}}, временно удалите ngFor. Вы также можете использовать оператор tap RxJS внутри pipe(), например, tap(messages => console.log(messages) после внешнего оператора map(). Нам просто нужно увидеть структуру того, что создает map(). Вы можете добавить это обновление к своему вопросу, чтобы его можно было лучше отформатировать / просмотреть. - person Alexander Staroselsky; 09.01.2019
comment
что печатает нормально. [{_name: Vik Kumar, _message: you rock shreya, _date: 1547063988434, _uid: 6jXG9ZQFghQA0l5M9qOx4UIqNhB2}, {_name: Vik Kumar, _message: Это потрясающее приложение. Я действительно счастлив, что могу написать вам прямо здесь. В восторге !!!, _date: 1547063988434, _uid: 6jXG9ZQFghQA0l5M9qOx4UIqNhB2}] - person Moblize IT; 09.01.2019
comment
Хорошо, попробуй еще кое-что. Вернитесь к *ngFor и на ion-list попробуйте поставить *ngIf="messages". - person Alexander Staroselsky; 09.01.2019
comment
:( не повезло с этим - person Moblize IT; 09.01.2019
comment
Используется ли messages где-нибудь еще в вашем шаблоне компонента? Есть ли в вашем шаблоне дополнительные *ngFor? - person Alexander Staroselsky; 09.01.2019
comment
нет, я могу подтвердить, что ngFor больше не используется на странице, и сообщения больше нигде не используются - person Moblize IT; 09.01.2019
comment
И просто для подтверждения, у вас все еще *ngFor="let msg of messages | async" на ion-item, верно? Также попробуйте альтернативу, которую я предложил. Спасибо - person Alexander Staroselsky; 09.01.2019
comment
Я думаю, ты сказал удалить асинхронный режим, что я и сделал. теперь добавил его обратно, и он работает нормально! - person Moblize IT; 09.01.2019