Rx Observable not updating when other component causes its data to update and call next


#1

update2 I’ve managed to distill the problem.

  • In the case of update happening on in same view as display of observable = The observable is firing everywhere and view updating correctly

  • In the case of the update happening in a different view, when returning to view that displays the observable = Observable in contact.store fires but not subscription on same var in contacts view

The only difference is the reference to the observable in the main view is gotten through a get method and returned as an asObservable()

Further! If I then make a call that modifies the data straight from the view after the fact, everything updates and it pulls the new and last update made from the child page. Perhaps something is not checking for some kind of event update?

summary
html view populated by observer which is feed by an http call which refreshes on any crud operations. Works perfectly if the call to the crud ops is done on same page as async view of observer data, but data does not appear refreshed if this is performed on a child page created by navCtrl.push after a pop

update
To test out the idea that it must be related to navCtrl I changed the AddContact button from going to blank detail page, this.navCtrl.push(ContactDetailPage); to instead just be adding a bunk new contact with this.contactsStore.addOrUpdateContact(new Contact("newna", "lastc", "next", "data.frequency")); – this works perfectly, the contact is added and the view immediately reflects this! The only difference is we’re navigating to and fro with push and pop. Very confusing.

Somewhat of a convoluted situation but I’m sure this is not a rare setup. I have a base.store which manages CRUD operations on my entities. One of these that implements base.store is contacts.store

The collection is exposed as an Observable and consumed as async in the View. base.store calls to update this collection on any crud operation.

When the crud ops were performed within the same component, upon an add/edit/etc everything worked perfectly and the view updated to show the updated data as soon as load() happened and updated the data.

However; now that I have split the add/edit/delete to its own page, the data doesn’t update after the pop. If I navigate away and back it does update though. I suspect it’s due to how I’m calling NavController push then pop for the data.

Below is example of code’s flow for the Add event

base.store

  protected options: {
    collection: string,
    model: string,
    route: string
  };
  protected _subject$: Subject<Array<any>>;
  protected dataStore: {};

  constructor(protected http: Http, protected configService: ConfigService, public authService: AuthService, public events: Events) { }
  init(options) {
    this.options = options;
    this.dataStore = {};
    this.dataStore[options.collection] = [];
    this._subject$ = <Subject<Array<any>>>new Subject();
    this.load();
  }

  load() {
    this.http.get(this.configService.getBaseUrl() + this.options.route + "?access_token=" + this.authService.getAccessToken()).map(response => response.json()).subscribe(
      data => {
        this.dataStore[this.options.collection] = data;
        this._subject$.next(this.dataStore[this.options.collection]);
      },
      error => {
        console.log('Could not load', this.options.collection, error);
      })
  }

  protected addEntity(entity: any) {
    this.http.post(this.configService.getBaseUrl() + this.options.route + "?access_token=" + this.authService.getAccessToken(), entity).subscribe(
      data => this.load(),
      err => console.log("Error addEntity", err));
  }

contacts.store

export class ContactStore extends BaseStore {

  protected _subject$: Subject<Array<Contact>>;
  options;

  constructor(protected http: Http, protected configService: ConfigService, public authService: AuthService, public events: Events) {
    super(http, configService, authService, events);

    this.options = {
      collection: "contacts",
      model: "Contact",
      route: "contacts"
    };
    this.init(this.options);
  }

  get contacts$() {
    return this._subject$.asObservable();
  }

  addOrUpdateContact(contact: Contact) {
    if(contact._id) this.updateEntity(contact);
    else this.addEntity(contact);
  }

contacts page, which actually displays the contact list

  public contacts$: Observable<Array<Contact>>;

  constructor(private contactsStore: ContactStore, public navCtrl: NavController, public events: Events) {
    this.contacts$ = this.contactsStore.contacts$; }

and the view

<ion-item (click)="contactDetail(contact)" *ngFor="let contact of contacts$ | async">{{contact.name}}</ion-item>

If user clicks add new contact from the main contact view they’re taken to a contact detail page via NavController.push; on there they fill in some details and hit save, on save all the contacts.store and base.store stuff kicks off and they’re returned to main contact list with NavController.pop. Via console debugging the load does indeed happen and the dataStore for contacts is updated, but for some reason the observable isn’t aware of this and the view isn’t updated until I navigate away and back.

Any ideas or solutions? The only thing really changed since it was working is now the crud is on its own page, and navigation occurs via navCtrl push and pop


#2

Contacts page’s constructor won’t be called again if you pop from contact detail page. So your

is not updated.


#3

@Ellezo Constructor doesn’t need to get called since contacts$ is subscribed to the observer which calls next() on an update from load. Per my update in the original… if the same add method is called from the parent page (without navigating anywhere), the view gets updated exactly as it should once load is called and subject.next fires.

The constructor does not fire in the case outlined in the update of my original post- yet changing the data via same method does cause the view to update correctly.


#4

Looks like this issue is more Rx/Angular related so I’m moving to stack overflow, http://stackoverflow.com/questions/40444410/rx-observable-not-updating-when-other-component-causes-its-data-to-update-and-ca