docs/docs/guides/developer-guide/channel-aware/index.mdx
Making an entity channel-aware means that it can be associated with a specific Channel.
This is useful when you want to have different data or features for different channels. First you will have to create
an entity (Define a database entity) that implements the ChannelAware interface.
This interface requires the entity to provide a channels property
import { DeepPartial } from '@vendure/common/lib/shared-types';
import { VendureEntity, Product, EntityId, ID, ChannelAware } from '@vendure/core';
import { Column, Entity, ManyToOne } from 'typeorm';
@Entity()
class ProductRequest extends VendureEntity implements ChannelAware {
constructor(input?: DeepPartial<ProductRequest>) {
super(input);
}
@ManyToOne(type => Product)
product: Product;
@EntityId()
productId: ID;
@Column()
text: string;
@ManyToMany(() => Channel) // [!code highlight]
@JoinTable() // [!code highlight]
channels: Channel[]; // [!code highlight]
}
Creating a channel-aware entity is similar to creating a regular entity. The only difference is that you need to assign the entity to the current channel.
This can be done by using the ChannelService which provides the assignToCurrentChannel helper function.
:::info
The assignToCurrentChannel function will only assign the channels property of the entity. You will still need to save the entity to the database.
:::
import { ChannelService } from '@vendure/core';
export class RequestService {
constructor(private channelService: ChannelService) {}
async create(ctx: RequestContext, input: CreateRequestInput): Promise<ProductRequest> {
const request = new ProductRequest(input);
// Now we need to assign the request to the current channel (+ default channel)
await this.channelService.assignToCurrentChannel(input, ctx); // [!code highlight]
return await this.connection.getRepository(ProductRequest).save(request);
}
}
For Translatable entities, the best place to assign the channels is inside the beforeSave input of the TranslatableSaver helper class.
When querying channel-aware entities, you can use the ListQueryBuilder or the TransactionalConnection to automatically filter entities based on the provided channel id.
import { ChannelService, ListQueryBuilder, TransactionalConnection } from '@vendure/core';
export class RequestService {
constructor(
private connection: TransactionalConnection,
private listQueryBuilder: ListQueryBuilder,
private channelService: ChannelService) {}
findOne(ctx: RequestContext,
requestId: ID,
relations?: RelationPaths<ProductRequest>) {
return this.connection.findOneInChannel(ctx, ProductRequest, requestId, ctx.channelId, { // [!code highlight]
relations: unique(effectiveRelations) // [!code highlight]
}); // [!code highlight]
}
findAll(
ctx: RequestContext,
options?: ProductRequestListOptions,
relations?: RelationPaths<ProductRequest>,
): Promise<PaginatedList<ProductRequest>> {
return this.listQueryBuilder
.build(ProductRequest, options, {
ctx,
relations,
channelId: ctx.channelId, // [!code highlight]
})
.getManyAndCount()
.then(([items, totalItems]) => {
return {
items,
totalItems,
};
});
}
}