0

I am using Zend Expressive 2 due to PHP version constraints. If I return variables in step one of pipeline (IndexAction) the variables appear just fine.

If I delegate to the next step (VerifyInputAction) and determine there is an error in the input, I need to return an error to view script. For some reason, it will not take the variables with it that I pass with the template renderer. It will still load the template, just not with the $data array variables.

I'm using Zend View as the template renderer.

My pipeline looks as follows.

IndexAction()

    public function process(ServerRequestInterface $request, DelegateInterface $delegate)
    {
        if ($request->getMethod() !== "POST") {
            return new HtmlResponse($this->template->render('app::home-page', ['error' => 'hello']));
        } else {
            $delegate->process($request);
            //return new HtmlResponse($this->template->render('app::home-page'));
        }
    }

VerifyInputaction()

    public function process(ServerRequestInterface $request, DelegateInterface $delegate)
    {
        $data = [];

        $file = $request->getUploadedFiles()['recordsFile'];

        $fileType = substr($file->getClientFilename(), strpos($file->getClientFilename(), '.'));

        // If file type does not match appropriate content-type or does not have .csv extension return error
        if (! in_array($file->getClientMediaType(), $this->contentTypes) || ! in_array($fileType, $this->extensions)) {
            $data['error']['fileType'] = 'Error: Please provide a valid file type.';
            return new HtmlResponse($this->template->render('app::home-page', $data));
        }

        $delegate->process($request);
    }

Another problem that might be beyond the scope of this question includes, when I make it to the next Action in the pipeline, if I go to render a view script there I get this error...

Last middleware executed did not return a response. Method: POST Path: /<--path-->/ .Handler: Zend\Expressive\Middleware\LazyLoadingMiddleware

I will do my best to provide more code examples, but due to this being an issue at work I might have some problems with that.

Thanks!

1 Answers1

0

Last middleware executed did not return a response. Method: POST Path: /<--path-->/ .Handler: Zend\Expressive\Middleware\LazyLoadingMiddleware

An action needs to return a response. In your VerifyInputaction you don't return a response if there is no valid csv file. I'm guessing this happens in your case and the $delegate->process($request); is triggered, which probably doesn't call another action which returns a middleware.

Looking at your code, it makes more sense to call VerifyInputaction first, check if it is a post and verify. If any of those fails, go to the next action which would be IndexAction. This could display the form with an error message. You can pass error message within the request as explained here: https://docs.zendframework.com/zend-expressive/v2/cookbook/passing-data-between-middleware/

Pipeline:

  • VerifyInputaction -> Check POST, verify input -> redirect if success
  • IndexAction -> render template and return response

I don't see any reason in your code why $data is not passed. My guess is that somehow the template is rendered in IndexAction which doesn't have the $data but has error set. You might check for this. The confusion is here that you render the same template in 2 different actions. Using the solution I mentioned, you only need to render it in IndexAction.

xtreamwayz
  • 1,285
  • 8
  • 10
  • Thank you for you response! So I did a little bit of re-configuring and handled the get/post check in the routes.php file, so now the index action just returns the HTML response/template. The post request goes to the VerifyInputAction and then loads the RecordsAction based on the result of VerifyInputAction. Do you mind explaining to me how these pipelines work? Do the responses that I return go back to the first action that was loaded? If so, does that mean I set a variable to the $delegate->process() and then that will hold the data that is returned? Thanks so much for helping! – Brock Caldwell May 03 '19 at 13:08
  • An expressive app or any middleware app is like an onion. It has layers. It goes from the outside to the inside and back to the outside (through the same middleware it got in, only in reverse order). Example: ErrorMiddleware -> AuthMiddleware -> RouterMiddleware -> MyIndexAction (returns response) -> AuthMiddleware (does nothing) -> ErrorMiddleware (catches exceptions and handles displaying those). The important thing is that piped middleware is always executed in the order that they are added. https://docs.zendframework.com/zend-expressive/v3/getting-started/features/#flow-overview – xtreamwayz May 04 '19 at 15:51
  • You don't set a variable to $delegate->process(). You use the request to pass data around: https://docs.zendframework.com/zend-expressive/v2/cookbook/passing-data-between-middleware/ – xtreamwayz May 04 '19 at 15:55