Tom
Tom

Reputation: 795

Why doesn' this observable react?

The observable this.currentNodeFilters$ is defined in ngOnChanged because it uses an Input() (this.node) pushed from a parent component using ChangeDetectionStrategy.OnPush (immutable object).

This this.currentNodeFilters$ is used with current queryParams in combineLatest. I'm expecting that on any changes from this.currentNodeFilters$ or queryParams, the observable this.currentFilters$ to react. But nothing happens.

Question: Why is it not reacting to the changes ?

Here is my code:

import {Component, OnInit, ChangeDetectionStrategy, Input} from '@angular/core';
import {ActivatedRoute} from "@angular/router";
import {Observable} from "rxjs";

@Component({
  selector: 'filter-content',
  templateUrl: './filter-content.component.html',
  styleUrls: ['./filter-content.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class FilterContentComponent implements OnInit {

  public currentNodeFilters$: Observable<any>;
  public currentFilters:any;

  @Input() node;

  constructor(private route: ActivatedRoute) { }

  ngOnChanges() {
    this.currentNodeFilters$ = Observable.of({
        "params": {
          "nodes": this.node.id
        },
        "order": "asc"
      }
    )
  }

  ngOnInit() {
    const queryParams$ = this.route.queryParams;

    // On regarde les queryParams pour construire currentFilters
    Observable.combineLatest(this.currentNodeFilters$, queryParams$, (currentFilter, queryParams) => {
        const p = Object.keys(queryParams).map(key => {
          const params = {};
          params[key] = queryParams[key];
          return Object.assign({}, {"params": params})
        })

        return Object.assign({}, currentFilter, p);
      })
      .subscribe(currentFilters => this.currentFilters = currentFilters)

   }
}

And the hml file subscribing

node: {{node | json}} from filter-content<br>
currentNodeFilters$: {{currentNodeFilters$ | async | json}}<br>
currentFilters: {{currentFilters | json}}

Upvotes: 0

Views: 126

Answers (1)

KwintenP
KwintenP

Reputation: 4775

The main problem I see is that your redefining the currentNodeFilters$ observable on every ngOnChanges. While instead you should be pushing a new value through the observable every time your ngOnChanges method has been called. Instead, you should be using a Subject if you want to do something like this. Your code would look like this:

// Create a subject instead of an observable
public currentNodeFilters$: Subject<any> = new Subject();
public currentFilters:any;

@Input() node;

constructor(private route: ActivatedRoute) { }

ngOnChanges() {
    // next the value through the subject
    this.currentNodeFilters$.next{
        "params": {
          "nodes": this.node.id
        },
        "order": "asc"
      }
    )
  }

Upvotes: 1

Related Questions