@Chain
export declare let Chain: (Class: any, key?: any, paramIndex?: any) => any;
Each controller has action chain which starts with interceptor filter and end with response filter.
@Chain can be used only as method parameter in action decorators.
@Chain is used to inject data from chained action:
@Filter(100)
export class Cache implements IFilter {
before(dataFromFilterBefore: string | Buffer): string|Buffer|Promise<string|Buffer> {
return "1";
}
after(dataFromActionChains: string | Buffer): string|Buffer|Promise<string|Buffer> {
return "7" + dataFromActionChains;
}
}
@Controller({
name: "home"
filters: [Cache]
})
export class HomeController {
@BeforeEach
beforeEachAction(@Chain dataFromFilter: string) {
return "2" + dataFromFilter;
}
@Before("action")
beforeAction(@Chain dataFromBeforeEach: string) {
return "3" + dataFromBeforeEach;
}
@Action("action")
processAction(@Chain dataFromBefore: string) {
return "4" + dataFromBefore;
}
@After("action")
afterAction(@Chain dataFromAction: string) {
return "5" + dataFromAction;
}
@AfterEach
afterEachAction(@Chain dataFromAfterAction: string) {
return "6" + dataFromAfterAction;
}
}
If you would execute this action chain you would get result 7654321.
Do you need to define action chains and filters ?
No, It's perfectly fine to define just @Action
@Controller({
name: "home"
})
export class HomeController {
@Action("action")
processAction(@Chain data: string) {
return "1" + data;
}
}
In this case @Chain data is empty and you would get result 1undefined.
Do I need to define @Chain in action ?
No if you don't chain actions.
So you probably wondering why do I have chains at all ?
Chains are designed to have shared business logic on different routes or to differentiate some business logic with rendering logic in @Before and in @Action.
You may want to use @BeforeEach to check user session for this controller.
The point is that you can stop chain at any time in logic of your code.
@Controller({
name: "home"
})
export class HomeController {
@Inject(Request) request: Request;
@Inject(MyService) serviceA: MyService;
@BeforeEach
beforeEachAction() {
if (this.serviceA.shouldStopMe()) {
this.request.stopChain();
}
return "2";
}
@Action("action")
processAction(@Chain dataFromBefore: string) {
return "4" + dataFromBefore;
}
}
If shouldStopMe method returns "true" your action chain will be stoped and your result will be "2", beforeAction and processAction methods will not be chained.