angulartypescriptrxjsangular-datatablesbehaviorsubject

How to detect changes from BehaviorSubject and execute an action automatically based on the new value


I am using a BehaviorSubject to handle languages in angular project, also I'm using Angular Datatabels http://l-lin.github.io/angular-datatables/#/welcome, and I'm trying to change the language in the data table based on the value returned from the subscription, is there any way to achieve this?

thank you in advance.

// Service

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root',
})
export class SharedService {
  public lang = new BehaviorSubject<string>('en');
}

In the Component :

 ngOnInit(): void {
    // get language
    this.langServiceSupscribtion = this.sharedService.lang.subscribe((l) => {
      this.lang = l;
    });

    this.dtOptions = {
      pagingType: 'full_numbers',
      language: {
        paginate: {
          first: this.lang == 'ar' ? 'الأول' : 'First',
          previous: this.lang == 'ar' ? 'السابق' : 'Previous',
          next: this.lang == 'ar' ? 'التالي' : 'Next',
          last: this.lang == 'ar' ? 'الأخير' : 'Last',
        },
        search: this.lang == 'ar' ? 'ابحث:' : 'Search:',
        info:
          this.lang == 'ar'
            ? 'إظهار _START_ إلى _END_ من _TOTAL_ مدخلات'
            : 'Showing _START_ to _END_ of _TOTAL_ entries',
        lengthMenu:
          this.lang == 'ar' ? 'عرض _MENU_ مدخلات' : 'Show _MENU_ entries',
        emptyTable:
          this.lang == 'ar'
            ? 'لا يوجد بيانات متاحة في الجدول'
            : 'No data available in table',
        zeroRecords:
          this.lang == 'ar'
            ? 'لم يعثر على أية سجلات'
            : 'No matching records found',
        infoEmpty:
          this.lang == 'ar'
            ? 'إظهار 0 إلى 0 من أصل 0 مدخلات'
            : 'Showing 0 to 0 of 0 entries',
        processing: this.lang == 'ar' ? 'جارٍ المعالجة...' : 'Processing...',
      },
    };
}

Solution

  • First you should update your options inside your subscribe.

    ngOnInit(): void {
        this.langServiceSupscribtion = this.sharedService.lang.subscribe((l) => {
            this.lang = l;
            this.updateOptions();
        });
    }
    updateOptions() {
        this.dtOptions = {
            pagingType: 'full_numbers',
            language: {
                paginate: {
                    first: this.lang == 'ar' ? 'الأول' : 'First',
                    previous: this.lang == 'ar' ? 'السابق' : 'Previous',
                    next: this.lang == 'ar' ? 'التالي' : 'Next',
                    last: this.lang == 'ar' ? 'الأخير' : 'Last',
                },
                search: this.lang == 'ar' ? 'ابحث:' : 'Search:',
                info: this.lang == 'ar' ?
                    'إظهار _START_ إلى _END_ من _TOTAL_ مدخلات' :
                    'Showing _START_ to _END_ of _TOTAL_ entries',
                lengthMenu: this.lang == 'ar' ? 'عرض _MENU_ مدخلات' : 'Show _MENU_ entries',
                emptyTable: this.lang == 'ar' ?
                    'لا يوجد بيانات متاحة في الجدول' :
                    'No data available in table',
                zeroRecords: this.lang == 'ar' ?
                    'لم يعثر على أية سجلات' :
                    'No matching records found',
                infoEmpty: this.lang == 'ar' ?
                    'إظهار 0 إلى 0 من أصل 0 مدخلات' :
                    'Showing 0 to 0 of 0 entries',
                processing: this.lang == 'ar' ? 'جارٍ المعالجة...' : 'Processing...',
            },
        };
        this.rerender() // Implement rerender function based on angular-datatables example.
    }
    

    What you have done looks correct but it feels that you are missing to re-render your table once you have updated options. You can check below page for how re-renderer your table.

    http://l-lin.github.io/angular-datatables/#/advanced/rerender