I have an angular service that consumes rest api.
@Injectable({
providedIn: 'root'
})
export class ProductService {
private url: string = "/app/products";
constructor(private http: HttpClient) {
}
get(caregoryId: string) {
return this.http.get<Product[]>(`${this.url}`)
.pipe(map(products => products.filter(p => p.caregoryId == caregoryId)))
}
add(p: Product) {
return this.http.post<Product>(this.url, p);
}
}
And my component is:
export class ProductComponent implements OnInit{
items: Observable<Array<Product>>;
ngOnInit() {
this.route.params.subscribe(
(params: any) => {
this.items = this.productService.get(params.id);
})
}
addWidget() {
let item: any = { name: "p-1", color: "red" } }
this.productService.add(item))
/// how to add created item in my items array ?
}
}
I can get list of products and list them using async pipe in html. But I could not add the created item in my observable array. How can I do it?
items$
every time you perform an operation in list (add, remove, update, etc.), you could use rxjs#Subject
, rxjs#merge
and rxjs#scan
to control the data flow;rxjs#switchMap
and do something like this:this.activatedRoute.paramMap.pipe( map((params) => params.id), switchMap((id) => this.productsService.getItems(id)) )
caRegory
:)With these changes, we have this:
@Component({
// ...
})
export class AppComponent {
readonly items$: Observable<readonly Product[]>;
private readonly insertedItemSource$ = new Subject<Product>();
private readonly insertedItem$ = this.insertedItemSource$.asObservable();
constructor(
private readonly activatedRoute: ActivatedRoute,
private readonly productsService: ProductsService
) {
this.items$ = merge(
this.activatedRoute.params.pipe(
map((params) => params.id),
switchMap((id) => this.productsService.getItems(id))
),
this.insertedItem$
).pipe(scan((accumulator, value) => [...accumulator, value]));
}
addWidget(): void {
const item: Product = { color: 'purple', name: 'p-3' };
this.productsService.add(item).subscribe(itemInserted => this.itemInsertedSource$.next(itemInserted));
}
}