Подписка на Angular Наблюдаемые доходы Пустой массив Angular 9 - PullRequest
0 голосов
/ 30 марта 2020

TL; DR; Как получить массив Role [] из Observable в мой компонент «Редактор меню»?


Я потратил несколько часов на поиск в Google. Это должно быть кусочком пирога в моей голове, но я просто хочу понять поведение здесь, чтобы избежать этой проблемы в будущем. (Я упустил как можно больше кода для упрощения вещей)

У меня есть компонент редактора меню (родительский компонент), он перебирает мой список пунктов меню, внедряя элемент меню в дочерний редактор меню компонент как menuItem. В дочернем компоненте у меня будет форма, с помощью которой пользователь может редактировать пункт меню. В дочерней форме мне нужен массив ролей в приложении, чтобы я мог создать список флажков для их выбора.

Для этого я создал службу ролей, и я могу вызвать API et c. Здесь все работает.

Затем я внедряю службу ролей в редактор пунктов меню, и я могу подписаться и перебрать *ngFor над roles наблюдаемой службой ролей. Отлично.

Я хочу поместить массив ролей в component.ts для редактора, чтобы я мог начать создавать Reactive Forms. Однако, когда я подписываюсь на наблюдаемое из службы ролей, оно пустое.

Когда я пытаюсь console.log() внутри метода подписки, это делает что-то очень странное в журнале. (Фото прилагается).

Нарисовано 14 элементов редактора меню (плюс 1 для «добавления нового»). Но я получаю 30 сообщений журнала консоли, и первые 15 пусты, а вторые 15 имеют значения.

role.service.ts

@Injectable({
  providedIn: 'root'
})
export class RoleService {
  private roleSubject: BehaviorSubject<Role[]> = new BehaviorSubject([]);
  roles: Observable<Role[]> = this.roleSubject.asObservable();

  constructor(private http: HttpClient) {
    this.getAllRoles().subscribe();
   }

  getAllRoles() {
    return this.http.get<Role[]>(`${environment.privateApiUrl}/Role/Get`).pipe(
      map(data => {
        this.roleSubject.next(data)
      }),
      catchError(<T>(error: any, result?: T) => {
        console.log(error);
        return of(result as T);
      })
    )
  }

}

role.ts

export class Role {
  id: number;
  roleName: string;
}

menu-manager-item -edit.component.ts

export class MenuManagerItemEditComponent implements OnInit {

  public roles: Role[] = [];
  @Input() public menuItem: SideMenuItem;

  constructor(public roleService: RoleService) {

    this.roleService.roles.subscribe(response => {
      console.log(response)
      this.roles = response;
    })

  }
  ngOnInit(): void {}

}

Console Output

1 Ответ

0 голосов
/ 30 марта 2020

Вероятно, вы увеличили подписку на Observable 15 раз, поэтому вы получите 15 раз console.log. Почему вы получаете пустой массив, а затем массив с Roles? Просто. Вы используете BehaviorSubject, в котором хранится значение, и каждый раз, когда вы подписываетесь на него, оно изначально отправляет сохраненное значение. Вот почему вам нужно установить начальное значение. Как только вы передадите значение next, оно уведомит каждого подписчика новым значением. Но помните, что когда вы подписываетесь, вы получите последнее сохраненное значение.

...