amikitevich
7/20/2017 - 1:15 PM

Input property to ReplaySubject

/**
 * service that emulates http
 */
@Injectable()
export class TodoService {

  readonly todos = [
    {id: 1, text: 'todo1', categoryId: 1},
    {id: 2, text: 'todo2', categoryId: 2},
    {id: 3, text: 'todo3', categoryId: 1},
    {id: 4, text: 'todo4', categoryId: 1}
  ];

  readonly todoCategory = [
    {id: 1, name: 'todoCategory1'},
    {id: 2, name: 'todoCategory1'}
  ];

  public getTodoItems() {
    return Observable.of(this.todos);
  }

  public getCategory(categoryId: number) {
    const category = this.todoCategory.find(item => item.id === categoryId);
    return Observable.of(category);
  }

}

@Component({
  selector: 'todo-list',
  template: `<todo-item *ngFor="let item of items$ | async" [todo]="item"></todo-item>`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class TodoListComponent implements OnInit {
  
  public items$: Observable<Todo[]>;
  
  constructor(private todoService: TodoService) { }
  
  ngOnInit() {
    this.items$: Observable<Todo[]> = this.todoService.getTodoItems();
  }

}

@Component({
  selector: 'todo-item',
  template: `Category: {{categoryName$ | async}}: {{todoText$ | async}}`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class TodoItemComponent implements OnInit {

  readonly todo$ = new ReplaySubject<Todo>(1);

  public todoCategoryName$: Observable<TodoCategory>;

  @Input() set todo(value: Todo) {
    this.todo$.next(value);
  }

  constructor(private todoService: TodoService) { }

  ngOnInit() {

    this.todoCategoryName$ = this.todo$
      .switchMap(todo => this.todoService.getCategory(todo.categoryId))
      .pluck('name');
  }

}

}