Search code examples
angulartypescriptangular-materialangular-routing

How do I get data loaded in an Angular Service into two components at the same time?


I've got an angular component that loads a client from the database using a service. Rather than keep returning to the database for every component, I am caching this data in the service as the Selected Client.

export class ClientService {
  Clients: Client[];

  constructor() {
    this.Clients = [
      {
        client:  0,
        name: "Fred",
        street: "Brockton Drive",
        address1: null,
        address2: null,
        city: "SomewhereVille",
        zipcode: "1234"
        },
        {
          client:  1,
          name: "Wilma",
          street: "Somerset Drive",
          address1: null,
          address2: null,
          city: "Elsewhere",
          zipcode: "0987"
          },
    ]
   }

  setCurrentClient(id: number) {
    var client = this.Clients[id];
    console.log(client);
    this.selectedClient.next(client);

  }

  readonly selectedClient: Subject<Client> = new Subject<Client>()

}

Then in the Client component I subscribe to the route parameters, and tell the client service to load the client, and set the selectedClient.

export class ClientComponent implements OnInit {

  constructor(private route: ActivatedRoute, private router: Router, private clientService: ClientService) {
    console.log("order component activated");

      route.paramMap.subscribe((params: ParamMap) => {
        const cid = params.get("id");
        if (cid)
          clientService.setCurrentClient(Number.parseInt(cid));
        else
          this.selectedClient = undefined;
      })
     clientService.selectedClient.subscribe((data) => this.selectedClient = data)

  }

  selectedClient?: Client;

  ngOnInit(): void {
  }
}

In the Client Details component, I then subscribe to the client service - selected client. This is the part that isn't working. As the details don't get filled out.

export class ClientDetailsComponent implements OnDestroy {


  ClientForm: FormGroup;
  token?: Subscription;

  constructor(private clientService: ClientService, private formBuilder: FormBuilder) {

    this.ClientForm = this.formBuilder.group<Client>(new Client());
     this.token = this.clientService.selectedClient.subscribe((data) => {
      this.selectedClient = data;
      this.ClientForm.setValue(this.selectedClient);
      console.log("Client activated");
    })
  }

  ngOnDestroy(): void {
    if(this.token) this.token.unsubscribe();

  }

  selectedClient?: Client;

  onSubmit(): void {

  }


}

What am I doing wrong, or against best practices, that is causing this not to work?

P.S. there is a stackblitz example - https://stackblitz.com/github/PhoenixStoneham/TabDataVanishing


Solution

  • You were almost there. The issue is that you are using Subject, instead of behavior subject.

    That means that it will only get the next value after it starts listening.

    So the client that was the selected one, won't have its value under client details b/c it won't emit any value.