phpzend-frameworkzend-viewmezzio

Zend Expressive not passing variables to view script


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!


Solution

  • 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:

    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.