Error while creating a Reactive Provider for multiple Ionic pages

Hello,

I am trying to build a reactive provider (that is, using RxJS to create, update and delete users – in my app, they are children).

I have two pages. One creates and deletes the children (HomePage). The secondary page updates the children info (EditChildPage). They call methods on the ChildrenService to do the update, delete and create operations.

Before showing you the classes that I have, the creating and deleting work fine because they are in the HomePage. Previously, I had the creating part in another page and it would call the children service, but the HomePage would not get updated. I just moved the creating into the same page and it worked fine. However, editing a person in a new page is really need and I am wondering if this is an Ionic issue. Why would a method act different if one page called it, instead of another? (By the way, I add the next page via this.nav.push(EditChildPage))

Here are the files in question:

ChildrenService

@Injectable()
export class ChildrenService {

  public children: Observable<Child[]> = new Observable<Child[]>();
  private updates: Subject<IChildOperation> = new Subject<IChildOperation>();
  private createStream: Subject<Child> = new Subject<Child>();
  private deleteStream: Subject<Child> = new Subject<Child>();
  private updateStream: Subject<Child> = new Subject<Child>();

  constructor(private http: Http) {
    this.children = this.updates
    .scan((children : Child[], operation: IChildOperation) => {
        return operation(children);
      }, []);

    this.createStream
    .map((newChild: Child) => {
      return (curChildren: Child[]) => {
        console.log("Creating a new child via stream.");
        return curChildren.concat(newChild);
      }
    })
    .subscribe(this.updates);

    this.updateStream
    .map((childToUpdate: Child) => {
      console.log("returning updateStream function...");
      return (curChildren: Child[]) => {
        console.log("Updating a child via stream.");
        return curChildren.map(nextChild => {
          if (nextChild._id == childToUpdate._id) {
            console.log(childToUpdate);
            return childToUpdate;
          }
          return nextChild;
        });
      }
    })
    .subscribe(this.updates);

    this.deleteStream
    .map((child : Child) => {
      return (curChildren: Child[]) => {
        console.log("Deleting a child via stream.");
        return curChildren.filter(nextChild => {
          return nextChild._id !== child._id;
        });
      }
    })
    .subscribe(this.updates);

    this.loadAll();
  }

  createChild(newChild: Child) {
    console.log("Creating child...");
    this.http.post(`${Constants.CHILDREN_API}`, newChild)
    .map(res=>res.json())
    .subscribe((createdChild: Child) => {
      console.log("Child Created!");
      console.log(createdChild);
      this.createStream.next(createdChild);
    });
  }

  updateChild(childToUpdate: Child) {
    console.log("Updating child...");
    this.http.put(`${Constants.CHILDREN_API}/${childToUpdate._id}`, childToUpdate)
    .map(res => res.json())
    .subscribe(updatedChild => {
      console.log("Child updated.");
      console.log(updatedChild);
      this.updateStream.next(updatedChild);
    });
  }

  deleteChild(child: Child) {
    console.log("Deleting child...");
    this.http.delete(`${Constants.CHILDREN_API}/${child._id}`)
    .subscribe(response => {
      console.log("Child deleted.");
      console.log(response);
      if (response.ok) this.deleteStream.next(child);
    });
  }

  loadAll() {
    this.http.get(`${Constants.CHILDREN_API}`)
    .map(res => res.json())
    .subscribe(
      (children: Child[]) => { // on success
        console.log(children);
        children.forEach(child => {
          this.createStream.next(child);
        });
      },
      (err: any) => { // on error
        console.log(err);
        // this.loading.emit(false);
      },
      () => { // on completion
        // this.loading.emit(false);
      }
    );
  }

  loadChild(childId: String, event: Subject<Child>) {
    return this.http.get(`${Constants.CHILDREN_API}/${childId}`)
    .map(res => res.json())
    .subscribe(
      (child: Child) => {
        event.next(child);
      },
      (err: any) => { // on error
        console.log(err);
      },
      () => { // on completion

      }
    );
  }
}

HomePage

export class HomePage implements OnInit {
  newChild: Child;
  showDelete: boolean;
  children: Observable<Child[]>;
  constructor(private nav: NavController, private childrenService: ChildrenService) {}

  ngOnInit(): any {
    this.newChild = new Child({ name: "" });
    this.showDelete = false;
    this.children = this.childrenService.children;
  }
  
  addChild(): any {
    this.childrenService.createChild(this.newChild);
    this.newChild.name = "";
  }

  editChild(child: Child): any {
    if (!this.showDelete) {
      this.nav.push(EditChildPage, { childId: child._id });
    }
  }
}

EditChildPage

export class EditChildPage implements OnInit {

  curChild: BehaviorSubject<Child> = new BehaviorSubject<Child>(null);

  constructor(private childrenService: ChildrenService, private navCtrl: NavController, private navParams: NavParams,
              private elementRef: ElementRef) {
    Observable.fromEvent(elementRef.nativeElement, 'keyup')
    .debounceTime(300)
    .map((event: any) => {
      let updatedChild = this.curChild.getValue();
      console.log("event", event.target.value);
      console.log(this.curChild.getValue());
      updatedChild.name = event.target.value;
      console.log(updatedChild);
      this.childrenService.updateChild(updatedChild);
      return updatedChild;
      // return new Child(updatedChild);
    })
    .distinctUntilChanged()
    .subscribe(updatedChild => this.curChild.next(updatedChild));
  }

  ngOnInit(): any {
    this.childrenService.loadChild(this.navParams.get("childId"), this.curChild);
  }
}

In the ChildrenService, you can see that I have a few console.logs where it says Creating a child via a stream. When I call the ChildrenService from the HomePage, I see that log (as well as Deleting a child via a stream), but when I call ChildrenService.updateChild through the EditChildPage, the log "Updating a child via a stream" is not called.

Any ideas on what this might be?

I did figure out a bug in the code where I called in ChildrenService.getAll():

children.forEach(child => {
   this.createStream.next(child);
});

After reviewing it, I realized this doesn’t make sense. However, after creating a reset stream that cleared all items from the stream, this then worked.

However, doing any update/create/delete in any other page but the first still errors out…