1
votes

I am using rxjs BehaviorSubject to create a service, upon sending values from Component1 and on subscribing in Component3, I get the values in Component3, this is achieved

Service file

`import { Injectable } from '@angular/core';
 import { Observable } from 'rxjs';
 import { BehaviorSubject } from 'rxjs/BehaviorSubject';

   @Injectable()
   export class UserService {

     constructor() { }

     // Observable navItem source
     public _navItemSource = new BehaviorSubject(undefined);

     // Observable navItem stream
     navItem$ = this._navItemSource.asObservable();

     // service command
     changeNav(nu) {
       this._navItemSource.next([...nu]);
     }
  }`

Component1

  `this._userService.changeNav(self.notificationslist);`

Component3

  `this.subscription = this._userService.navItem$.subscribe(item =>   
   this.item1 = item);`

Now I want to use the same service in one more component(Component2) to send some different values to the same component Component3

Component2

 `this._userService.changeNav(this.updatedFlag);`

Component3

  `this.subscription = this._userService.navItem$.subscribe(item =>   
   this.item1 = item);`

And then upon subscribing it on Component3 I should get all the values from Component1 and Component2. So I have updated my service file but I get the following error

caused by: this._navItemSource.asObservable(...).scan is not a function

Please correct me where I am going wrong as I am new to rxjs.

Updated Service file

`import { Injectable } from '@angular/core';
 import { Observable } from 'rxjs';
 import { BehaviorSubject } from 'rxjs/BehaviorSubject';

 @Injectable()
 export class UserService {

 constructor() {
 }

  // Observable navItem source
  public _navItemSource = new BehaviorSubject(undefined);

  // Observable navItem stream
  navItem$ = this._navItemSource.asObservable().scan((acc, one) =>(acc + 
  one));

  // service command
  changeNav(nu) {
    this._navItemSource.next([...nu]);
  }

}`
1
make sure you import scan operator! import "rxjs/add/operator/scan";JayDeeEss
Thanks alot @JayDeeEss that error has due to scan operator not being imported ,but I am only getting the value of Component1 but not from Component2, I am passing an array from Component1 and a single value from Component2Enthu
your function doesn't look right if one is array and other is single value. You either have to somehow return array from both and merge into one or return a json where first is array and second is single value as scan always going to return one valueJayDeeEss
ok I have already defined updatedFlag = [] in Component2, but I thought just for info I'll tellEnthu
ok then you can use concat() to merge 2 arrays if thats what you want developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…JayDeeEss

1 Answers

1
votes

make sure you import scan operator. and in the scan function to merge your results you can return a JSON with the previous and new value emitted

Working Plunker

import { Injectable } from '@angular/core';
 import { Observable } from 'rxjs';
 import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import "rxjs/add/operator/scan";
 @Injectable()
 export class UserService {

 constructor() {
 }

  // Observable navItem source
  public _navItemSource = new BehaviorSubject(Object([]));

  // Observable navItem stream
  navItem$ = this._navItemSource.asObservable().scan((acc, one) => {
                    return {
                        'previous': acc, 'new': one
                    }
                });

  // service command
  changeNav(nu) {
    this._navItemSource.next([...nu]);
  }

}