angularangular16

Angular component, not updating frontend


I have a chatbot component that I charge in my app.component.html to access it everywhere.

<app-chatbot [enable]="this.enableSerenia"></app-chatbot>

In my chatbot component, I have multiples variables accessible from outside using @Input();

export class ChatbotComponent implements OnChanges {
    @Input() enable: boolean = false;
    @Input() actionsList: any[] = [];
    @Input() messagesList: any[] = [];
    @Input() showDialog: boolean = false;
    @Input() newNotification: boolean = false;
}

In another component, I need to update some of thoses chatbot variables. So I declare it in my another component constructor, and update the variable like this :

constructor(
    private serenia: SereniaChatbotComponent // EDISSYUM - NCH01 Implémentation SerenIA
) {
    this.serenia.newNotification = true;
}

But the variable is not updated on my frontend. What do I need to "update" my frontend when I update my chatbot variable from another component ?

I'm under Angular 16


Solution

  • Create a service specific for the chatbot. Make sure it is provided in root so that it is accessible from anywhere in your application.

    We initialize a subject and an observable, the reason for this, is to trigger change detection in the chatbot component.

    @Injectable({ providedIn: 'root' })
    export class ChatBotService {
        private subject: Subject<void> = new Subject<void>();
        private chatObs$: Observable<void> = this.subject.asObservable();
    
        enable: boolean = false;
        actionsList: any[] = [];
        messagesList: any[] = [];
        showDialog: boolean = false;
        newNotification: boolean = false;
    
        refresh() {
          this.subject.next();
        }
    }
    

    Use the ChatBotService in the app component. We use

    export class AppComponent {
      public chatBotService = inject(ChatBotService);
    }
    

    Then bind this service properties in the app component.

    <app-chatbot [enable]="chatBotService.enableSerenia"></app-chatbot>
    

    You might not see the values refreshed, so we need to trigger the change detection from the chatbot component. We use the observable we created earlier to do this.

    @Component({ ... })
    export class ChatBotComponent {
      private sub = new Subscription();
      private cdr = inject(ChangeDetectorRef);
      ...
      constructor() {
        this.sub.add(
          this.chatBotService.chatObs$.subscribe(() => {
            this.cdr.detectChanges();
          })
        );
      }
      ...
      ngOnDestroy() {
        this.sub.unsubscribe();
      }
    }
    

    Now just modify the values from wherever in your application and it should work.

    @Component ({ ... })
    export class SomeComponent {
      private chatBotService = inject(ChatBotService);
      
      constructor() {
        this.chatBotService.enable = true;
        this.chatBotService.refresh(); // trigger change detection so the values are refreshed.
      }