Combining Multiple Stores with Akita
Present a code example of combining data from multiple Akita stores into a single observable stream using RxJS operators in the context of an Angular application.
import { Injectable } from '@angular/core';
import { combineLatest } from 'rxjs';
import { Store, Query } from '@datorama/akita';
export interface User {
id: number;
name: string;
}
export interface Product {
id: number;
title: string;
}
@Injectable({ providedIn: 'root' })
export class UsersStore extends Store<User> {
constructor() {
super();
}
}
@Injectable({ providedIn: 'root' })
export class UsersQuery extends Query<User> {
constructor(protected store: UsersStore) {
super(store);
}
selectUsers() {
return this.select();
}
}
@Injectable({ providedIn: 'root' })
export class ProductsStore extends Store<Product> {
constructor() {
super();
}
}
@Injectable({ providedIn: 'root' })
export class ProductsQuery extends Query<Product> {
constructor(protected store: ProductsStore) {
super(store);
}
selectProducts() {
return this.select();
}
}
This code snippet contains the setup for two Akita stores and queries: UsersStore and ProductsStore. Both are decorated with @Injectable, meaning they can be injected as dependencies in Angular components or services. The `UsersQuery` and `ProductsQuery` classes can be used to select data from the stores.
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { combineLatest } from 'rxjs';
import { UsersQuery } from './users.store';
import { ProductsQuery } from './products.store';
@Component({
selector: 'app-user-products',
template: `<div *ngFor="let item of combinedData$ | async">{{item | json}}</div>`
})
export class UserProductsComponent implements OnInit {
combinedData$: Observable<any>;
constructor(private usersQuery: UsersQuery, private productsQuery: ProductsQuery) { }
ngOnInit() {
this.combinedData$ = combineLatest([
this.usersQuery.selectUsers(),
this.productsQuery.selectProducts(),
]).pipe(
map(([users, products]) => ({ users, products })) // Combines user data and product data
);
}
}
This code snippet defines an Angular component that combines data from the UsersQuery and ProductsQuery using RxJS's `combineLatest` function. The combined data is stored in `combinedData$`, which is an Observable stream and can be subscribed to or used with the `async` pipe in the component template. The `map` function is used to transform the data emitted by the combined observables into a single object with `users` and `products` as properties.