How to call another presenter from inside a handler (code port / general question)?

stephansteiner
Member | 3
+
0
-

Hi, I'm trying to port old Nette 2.0.4 code to 3.x.
Inside a form handler “handleSave()” I found the following code that creates a subrequest to another module:

 		// process subreq
        $request = new \Nette\Application\Request(':Api:Queue', 'POST', $params, $post, $files);
        $presenter = new \ApiModule\QueuePresenter($this->getContext());
        $response = $presenter->run($request);

        $this->flashMessage($response->getSource());

This called the a presenter class which is also available as HTTP Rest API call. The result is displayed with a flashMessage.

However, this code doesn't work in Nette 3.0.
Any idea on how to fix it? Or is there another way to do a subrequest to another mode?

nightfish
Member | 472
+
0
-

stephansteiner wrote:
However, this code doesn't work in Nette 3.0.

Could you please clarify what code doesn't work mean? Is there an error message? Does the code run, but the $response does not contain what you expect?

Last edited by nightfish (2021-04-28 19:22)

stephansteiner
Member | 3
+
0
-

The line with

$presenter->run($request);

generates the exception
Error: Call to a member function isSent() on null in /Users/stephan/htdocs/gwoo/vendor/nette/application/src/Application/UI/Presenter.php on line 200

David Matějka
Moderator | 6445
+
+1
-

It is better to move the logic from the presenter to some service and call this service instead.

But if you really want to call the presenter, you have to create the presenter using Nette\Application\IPresenterFactory service.

/** @var \Nette\Application\IPresenterFactory @inject
public $presenterFactory;

// ....
$presenter = $this->presenterFactory->createPresenter('Api:Queue');
dakur
Member | 493
+
0
-

@DavidMatějka But the problem was that $this->httpResponse was null in Presenter (because Presenter#injectPrimary() was not called). When you create presenter with PresenterFactory, will it happen? I can't see it in source code, but maybe some magic happens in DI. 🤷‍♂️

David Matějka
Moderator | 6445
+
+1
-

@dakur yes, either the presenter is registered in the DI with inject tag, or callInject is called when creating a not registered presenter

dakur
Member | 493
+
0
-

Aha, so injectPrimary() is basically just another inject* method! I've never realized this, thanks.

stephansteiner
Member | 3
+
0
-

Thank you so much, it worked!