Reputation: 3274
I'm new in Angular and I'm trying to transfer the data between 2 siblings in real-time:
This is my service:
message-transfer-service.ts
import { Injectable } from '@angular/core';
import { Products } from './products';
import { Observable } from "rxjs/Observable";
import "rxjs/add/observable/of";
@Injectable({
providedIn: 'root'
})
export class MessageTransferService {
private products = new Products();
getProducts() : Observable<Products> {
if (this.products)
return Observable.of(this.products);
}
setProducts(product: Products) {
this.products = product;
}
constructor() { }
}
This is my first sibling:
products-list.component.ts
import { Component, OnInit, Input } from '@angular/core';
import { MessageTransferService } from '../message-transfer.service';
import { Products } from '../products';
@Component({
selector: 'app-products-list',
templateUrl: './products-list.component.html',
styleUrls: ['./products-list.component.css']
})
export class ProductsListComponent implements OnInit {
constructor(private service: MessageTransferService){ }
product: any;
ngOnInit() {
this.product = { "id": 1, "name": "Cat", "age": 30 };
this.setProducts();
}
setNewProduct() {
this.product = { "id": 2, "name": "Dog", "age": 30 };
this.setProducts();
}
setProducts() {
let d : Products = JSON.parse(JSON.stringify(this.product));
this.service.setProducts(d);
}
}
product-list.component.html
<p>products-list works!</p>
<button (click)="setNewProduct()">Set new book</button>
This is my second sibling:
product-details.component.ts
import { Component, OnInit } from '@angular/core';
import { MessageTransferService } from '../message-transfer.service';
import { Products } from '../products';
import { Observable } from 'rxjs';
@Component({
selector: 'app-product-details',
templateUrl: './product-details.component.html',
styleUrls: ['./product-details.component.css']
})
export class ProductDetailsComponent implements OnInit {
product: Observable<Products>;
constructor(private service: MessageTransferService){
}
ngOnInit() {
this.getProducts();
}
getProducts() {
this.product = this.service.getProducts();
console.log(this.product);
}
}
product-details.component.html
<p>product-details works!</p>
<button (click)="getProducts()">Click</button>
<p>{{product}}</p>
If I click on the button, the data is refreshed:
What I'm looking forward to is when I do click on the Set new book, its content should be automatically updated since the values are updated in the service, but until I do click on the button Click it's reflected in the console. Do you have any idea, what should I change? Probably is something in the constructor of product-details, but I'm not sure since I'm quite new in this area. Thanks for any hint.
I'm working with Angular 8 and the latest version of RXJS.
Upvotes: 2
Views: 1168
Reputation: 1933
You can save your list like this with BehaviorSubject
in your service:
export class MessageTransferService {
private productsSubject = new BehaviorSubject<Products[]>([]);
public products$ = this.productsSubject.asObservable();
setProducts(product: Products) {
const products = this.productsSubject.getValue();
products.push(product);
this.productsSubject.next(products);
}
}
And recover it by subscribing :
export class ProductDetailsComponent implements OnInit {
products: Products[];
constructor(private service: MessageTransferService){ }
ngOnInit() {
this.service.products$.subscribe(products => this.products = products)
}
}
setProducts(product)
of your service thus retrieves the existing list and adds the new product to the list.
Upvotes: 2
Reputation: 2330
Use BehaviorSubject
(Thanks @fredrik).
export class MessageTransferService {
private products = new Products();
products$ = new BehaviorSubject<Products>(this.products)
setProducts(product: Products) {
this.products$.next(product)
}
constructor() { }
}
export class ProductDetailsComponent implements OnInit {
product$: this.service.product$;
constructor(private service: MessageTransferService){
}
ngOnInit() {
}
}
<p>{{product$ | async}}</p>
Upvotes: 1
Reputation: 483
You are returning Observable and not subscribing it
export class MessageTransferService {
private products = new Products();
private productSubject = new BehaviorSubject<Product>(this.products);
getProducts() : Observable<Products> {
if (this.products)
return this.productSubject.asObservable();
}
setProducts(product: Products) {
this.products = product;
this.productSubject.next(this.products);
}
constructor() { }
}
and subscribe it in component
Upvotes: 1