简体   繁体   中英

Angular communication between unrelated components

I have two unrelated componets CartComponent and CheckoutComponent. I'd like pass data from CartComponent to CheckoutComponent. For this purpose I created Shared Service.

    export class CartService {
  private cartSubjectList = new Subject<Products[]>();
  currentSubjectList = this.cartSubjectList.asObservable();
  public cartCount = 0;
  constructor() {
    console.log('CartService log:', this.currentSubjectList);
   }

  setData(cartList: Products[]) {
    this.cartSubjectList.next(cartList);
  }
  getData() {
    return this.currentSubjectList;
  }
  getCartProducts(): Products[] {
    const products: Products[] = JSON.parse(localStorage.getItem('cart')) || [];
    return products;
   }

In CartComponent I set data to my cartSubjectList in setData method. 调试

 export class CartComponent implements OnInit {

      cartProducts: Products[];
      constructor( private cartService: CartService) { }
      ngOnInit() {
        this.getCart();
      }

      getCart() {
      this.cartProducts = this.cartService.getCartProducts();
      this.cartService.setData(this.cartProducts);
      }
}

In CheckoutComponent I would like to display my array but my checkoutProduct is undefined.

 export class CheckoutComponent implements OnInit {

  checkoutProducts: Products[];
  constructor(private formBuilder: FormBuilder, private cartService: CartService) { }

  ngOnInit() {
    this.cartService.getData().subscribe( data => {
      this.checkoutProducts = data;
      console.log(this.checkoutProducts);
    });
  }
}

Any help or suggestion is welcome

This is because you're using a Subject . A new subscriber to a Subject will not receive anything that was previously emitted unless it is a ReplaySubject or a BehaviorSubject .

I would recommend using ReplaySubject with a buffer length of 1:

private cartSubjectList = new ReplaySubject<Products[]>(1);

When a new subscription is made (via the CheckoutComponent ) it should immediately receive the previous emission.

You have to make sure that the two components use the same instance of the service. Where is the service provided? If both of these components are in the same module, provide the service in that module. If they are in different modules, ONLY provide the service in a module that imports both of the components' modules. ( AppModule is usually a safe choice.)

Also, with 6+ versions of Angular you are able set the provided modules from directly the service. Remove the service from all modules where it is provided, and try:

@Injectable({
    providedIn: 'root'
})

This should have the same result as providing the service only in the AppModule .

I must supouse your getCartProducts is an async call -you make a get or return an observable,so you need send values in the subscribe

getCart() {
  this.cartService.getCartProducts().subscribe(res=>{
     this.cartProducts =res;
     this.cartService.setData(this.cartProducts);
  });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM