Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

299
Views
*ngFor not updating, even with ChangeDetectorRef

I'm new to Angular, working with Angular 12 for a school assignment, trying to build a chat window of sorts that updates itself whenever the user sends a message, but I can't find a way to make it re-render when I add a new object to the array.

chat.component.ts:

@Component({
  selector: 'app-chat',
  templateUrl: './chat.component.html',
  styleUrls: ['./chat.component.scss']
})
@Injectable({  providedIn: 'root'  })
export class ChatComponent implements OnInit {
  messageArray: Array<any>;

  constructor(private changeDetector: ChangeDetectorRef) {
    this.messageArray = [{message: "test message 1", style: "answer"}];
  }
  ngOnInit(): void {}
  addMessage(message: string, style: string): void {
    this.messageArray = [...this.messageArray, {message: message, style: style}];
    this.changeDetector.detectChanges();
    console.log(this.messageArray);
  }

}

chat.component.html:

<div class="container chatContainer">
    <div class="row" *ngFor="let message of messageArray">
        <div class="col">
            <div class="text-wrap text-break message {{message.style}}">
                {{message.message}}
            </div>
        </div>
    </div>
</div>

I tried updating the array both with [...array] and with .push(), tried using [...array] to create a new array after pushing, tried both ChangeDetectionStrategy.Default and .OnPush, and tried doing all of those things also in the parent component that calls my addMessage() method. In all attempts, the array would log to the console correctly, but refuse to update the view.

Any ideas?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

If i were you, i would rather use a BehaviorSubject and do something like this:

@Component({
  selector: 'app-chat',
  templateUrl: './chat.component.html',
  styleUrls: ['./chat.component.scss']
})


@Injectable({  providedIn: 'root'  })
export class ChatComponent implements OnInit {
  messageArray: BehaviorSubect<Array<any>>;

  constructor(private changeDetector: ChangeDetectorRef) {
    this.messageArray = new BehaviorSubject<Array<any>>([{message: "test message 1", style: "answer"}]);
  }
  ngOnInit(): void {}
    addMessage(message: string, style: string): void {
    this.messageArray.next([...this.messageArray, {message: message, style: style}]);
  }
}

chat.component.html:

<div class="container chatContainer">
  <div class="row" *ngFor="let message of messageArray | async">
      <div class="col">
          <div class="text-wrap text-break message {{message.style}}">
              {{message.message}}
          </div>
      </div>
  </div>
</div>
over 4 years ago · Santiago Trujillo Report

0

A colleague suggested I use @ViewChild to call the Chat component instead. So I removed the @Injectable from the Chat as zer0 suggested, and changed its parent Home component to this:

export class HomeComponent implements OnInit {

  @ViewChild(ChatComponent) private chatComponent: any;

  constructor(private cdr: ChangeDetectorRef) {
  }

  ngOnInit(): void {
  }

  onSend(): void {
    this.chatComponent.addMessage("test message", "question");
    this.cdr.detectChanges();
  }

}

Works now. Thanks!

Edit: a word

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!