Issue with resetting child properties of BehaviorSubject whereas whole variable gets reset easily

39 Views Asked by At

So I am out of clues with this problem, and would really appreciate any help regarding it.

I have created an example to understand my problem. In this, we are filtering a few objects of students from the list of students and section having those students based on whether the account is active or not.

It's filtering just fine with students and sections at first but once sections have lost their few students, I am not able to reset the section student back to the original whereas the students' list gets reset.

Initially, the account is !active, it has 6 students and 2 sections with the second section having 6 students. When the account is active it has 4 students and section s2 should also have just 4 students, this is working fine, but when we switch the account to active again then students get reset with 6 values but the section is not getting reset.

The desired result would be to switch back to the second section with 6 students as well, after toggling the account's active status.

Please be lenient with me. Thanks in advance.

import { BehaviorSubject, combineLatest, filter, map, Observable } from 'rxjs';

interface arrType {
  id?: string;
  name?: string;
  child?: arrType[];
}

export class NavSer {
  constructor() {}
  toppers = ['first', 'second'];
  students = new BehaviorSubject<arrType[]>([]);
  sections = new BehaviorSubject<arrType[]>([]);
  isActive = new BehaviorSubject<boolean>(false);

  init = () => {
    const arr = [
      { id: '1', name: 'first' },
      { id: '2', name: 'second' },
      { id: '3', name: 'third' },
      { id: '4', name: 'forth' },
      { id: '5', name: 'fifth' },
      { id: '6', name: 'sixth' },
    ];
    this.sections.next([
      { id: 's1', name: 'iFirst' },
      { id: 's2', name: 'iSecond', child: arr },
    ]);
    this.students.next(arr);
  };

  getSections(): Observable<arrType[]> {
    return combineLatest([
      this.sections.asObservable(),
      this.isActive.asObservable(),
    ]).pipe(
      filter(([sections, isActive]) => {
        return sections !== undefined;
      }),
      map(([sections, isActive]) => {
        if (isActive) {
          sections[1].child = sections[1].child.filter((obj) => {
            return !this.toppers.some((obj2) => obj.name === obj2);
          });
        }
        return sections;
      })
    );
  }

  getStudents(): Observable<arrType[]> {
    return combineLatest([
      this.students.asObservable(),
      this.isActive.asObservable(),
    ]).pipe(
      filter(([students, isActive]) => {
        return students !== undefined;
      }),
      map(([students, isActive]) => {
        if (isActive) {
          students = students.filter((obj) => {
            return !this.toppers.some((obj2) => obj.name === obj2);
          });
        }
        return students;
      })
    );
  }

  changeAccount = () => {
    this.isActive.next(!this.isActive.value);
  };
}

var n = new NavSer();
n.init();
n.getStudents().subscribe((data) => {
  console.log('students', data);
});
n.getSections().subscribe((data) => {
  console.log('sections', data);
});
document
  .getElementById('changeAccount')
  .addEventListener('click', n.changeAccount);


Stackblitz link here

1

There are 1 best solutions below

4
Aakash Shah On

I know you have tried else condition inside getSections method because section[i].child needs to get updated when isActive is false. On init method we are assigning arr to section[1].child using next but when isActive is false we are not assigning the latest value to section[1].child.

Hope it helps you.