Pass Request object to Controller constructor
See original GitHub issueSorting
-
I’m submitting a …
- bug report
- feature request
- support request
-
I confirm that I
- used the search to make sure that a similar issue hasn’t already been submit
Expected Behavior
It would be useful to have the Request object in the controller constructor, not only on the handler method. It’s similar to what was asked on #7. The issue was solved in #25 for DI, but not for non-DI controllers. I don’t know if there is a reason for not doing it.
// In the generated routes.ts file
validatedArgs = getValidatedArgs(args, request, response);
const controller = new MyController(request)
const promise = controller.myHandlerMethod.apply(
controller,
validatedArgs as any
)
promiseHandler(controller, promise, response, undefined, next)
Current Behavior
The Controller constructor is called with no arguments.
Possible Solution
It seems to me that a simple change in the handlebars templates would do. For example, in the express.hb
, this is the current code:
{{#if ../../iocModule}}
const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
const controller: any = await container.get<{{../name}}>({{../name}});
if (typeof controller['setStatus'] === 'function') {
controller.setStatus(undefined);
}
{{else}}
const controller = new {{../name}}();
{{/if}}
Changing the else
part to:
{{else}}
const controller = new {{../name}}(request);
{{/if}}
Seems to do the job. It’s the same request
that is being passed to IoCContainerFactory
.
Breaking change?
Currently the constructor is called without arguments, I’m not sure adding an argument is breaking. Maybe for people that are using default parameters in the controller constructor? Like:
class MyController {
constructor(myArg = 'some default arg') {}
}
Issue Analytics
- State:
- Created 2 years ago
- Reactions:1
- Comments:5
Top GitHub Comments
A non breaking way could be to use a property of the controller. Maybe add a
request
property to the controller class and then inject that property from the route template after initialization. This way it is not interfering with other constructor arguments, independent if using DI or not and also spares to set a request like object in every unit test even if the method to test doesn’t need it (in contrary to constructor injection). If users want more control or do additional stuff on the request there could be an overridablesetRequest
orsetContext
method that the route template calls. For exmplaeand
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days