Home > Mobile >  Ngfor doesn't actualize on reloading page (Angular RXJS)
Ngfor doesn't actualize on reloading page (Angular RXJS)

Time:12-25

Hi i'm building a chat app with angular for a school project i'm using firebase for my backend and i have an issue with my ngfor.

For exemple if i reload the page i will see nothing unless i hover my routerlink on my navbar. However sometime it will work after some time on the page without any action

When i recieve message i need to be on the page to see them ...

When i reload my page in first time my array is empty this may be what makes the ngfor bug array on reload.

I'm using ngOnInit() to subscribe :

messages: Message[];
  messageSubscription: Subscription;

  constructor(private messageService: MessageService, private router: Router) { 
    
  }

  ngOnInit(): void {
    this.messageSubscription = this.messageService.messageSubject.subscribe(
      (messages: Message[]) => {
        console.log(messages)
        this.messages = messages;
      }
    );
    this.messageService.getMessage();
    this.messageService.emitMessage();
  }

  ngOnDestroy(): void {
      this.messageSubscription.unsubscribe();
  }

This is my html template :

<div *ngFor="let message of messages" >
    <img [src]="message.photoURL" >
    <div >
        <div >
            <p >{{message.displayName}}</p>
            <p >{{message.createdAt | date: 'short'}}</p>
        </div>
        <p >{{message.text}}</p>
    </div>
</div>

Here you can find my service with my getMessage() function and emitMessage():

  messages:Message[] = [];
  messageSubject = new Subject<Message[]>();
  constructor() { }

  emitMessage(){
    this.messageSubject.next(this.messages);
  }

  saveMessage(newMessage: Message){
    firebase.database().ref('/message').push(newMessage);
  }

  getMessage(){
    firebase.database().ref('/message')
      .on('value', (data) => {
        this.messages = data.val() ? Object.values(data.val()): [];
        this.emitMessage();
      });
  }

And this is the repo of my project: https://github.com/Zuxaw/AngularChatApp

If anyone has a solution I'm interested

CodePudding user response:

Problem is, your firebase library is not Angular specific.

This means you some times need to make sure its code, mostly its event callbacks, run within an Angular zone (google to read about it) to make sure a change detection 'tick' is invoked when data changes.

message.service.ts

import { Injectable, NgZone } from '@angular/core';

// ...

constructor(private zone: NgZone) { }

// ..

getMessage(){
  firebase.database().ref('/message')
    .on('value', (data) => {
      this.zone.run(() => {
        this.messages = data.val() ? Object.values(data.val()): [];
        this.emitMessage();
      });
    });
}

CodePudding user response:

I think you might need to use the child_added event instead of value in your getMessage method.
Check if you're receiving data on time in your getMessage method, if not it's most probably, because of the event.
But one thing that I don't understand is why you're calling emitMessage inside getMessage and also calling it inside your component after getMessage, try to evade that.

  • Related