lwin
lwin

Reputation: 4460

Angular multiple component share data by service not working

This is share service (dShareService) =>

@Injectable()
export class DInfoShareService {
    constructor() { }

    // Observable sources    
    private dInfo = new Subject<DInfo>();

    dInfo$ = this.dInfo.asObservable();

    // Service message commands
  public SetDInfo(dinfo: DInfo) {     
    this.dInfo.next(dinfo);
  }
}

This is parent =>

At the parent, I have the button click event and pass data to the method and value is the pass to service.

GoToDetail(value){       
    this.dShareService.SetDInfo(value);

    //this is child component and call by route, basically, I use this state and pass data to child 
    //component but this time, I have 3 tab page at UI and each page needs this data.
   
 this.router.navigateByUrl('/dchild', {
          state: {dInfo: value}
    });

This is the child component =>

At the constructor ,

this.dinfoShareService.dInfo$.subscribe(res=>
     {
       //this one never happen
       this.dInfo = res;
     } 
  );

This subscribes at the child is never trigger. May I know what I am wrong?

Upvotes: 0

Views: 637

Answers (3)

Eldar
Eldar

Reputation: 10790

You need to change your decorator into this @Injectable({ providedIn: 'root' }) to make it singleton across components. Else it will provide multiple instances for multiple components.

Also noticed that :

GoToDetail(value){       
    this.dShareService.SetDInfo(value);   
    this.router.navigateByUrl('/dchild', {
          state: {dInfo: value}
    });
}

The above code calls the SetDInfo method before the navigation. So your child component subscribes after the value set. You need to change your Subject to BehaviorSubject so that you can read the last set value.

Upvotes: -1

Rebai Ahmed
Rebai Ahmed

Reputation: 1600

You have a wrong implemntation for the Subject inisde your service :

@Injectable()
export class DInfoShareService {
    constructor() { }

    // Observable sources    
    private dInfo = new Subject<DInfo>();


    // Service message commands
  public SetDInfo(dinfo: DInfo) {     
    this.dInfo.next(dinfo);
  }
}

It not should be called inside the constructor, use it inside ngOninit

     ngOnInit(): void {

this.dinfoShareService.dInfo.subscribe(res=>
     {
       //this one never happen
       this.dInfo = res;
     } 
  );


});

Upvotes: 0

Prakash Harvani
Prakash Harvani

Reputation: 1041

Try Like this, Service.ts file

import { BehaviorSubject, Observable, throwError } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ApiWalletService {
  private behave = new BehaviorSubject<Object>('');

  setBehaviorView(behave: object) {
    this.behave.next(behave);
  }

  /** Get Behavior for user registraion */
  getBehaviorView(): Observable<object> {
    return this.behave.asObservable();
  }

}

component1.ts

 {
     ngOnInit() {
            this.setBehaviorView({
              'data':'XYZ'
            })
       }
    }

component2.ts

{

 constructor(private service: Service){}

 ngOnInit() {
 this.service.getBehaviorView().subscribe(async (data) => {
   if (data && data != undefined) {
      console.log(data)
    }
  })
}
}

Upvotes: 3

Related Questions