Search code examples
phprestapisymfonygoogle-books

Symfony API Request Unexpected "G"


I'm really thrown off by this error I get when posting to Google Books API. The last response in this function is triggered when I post 1781100489 to a form. This form then runs resultAction function. Instead of returning what I want it to, I get a JSON.parse error with an unexpected token in line 1 column 1.

When tested with Postman, it gives me this peculiar message in its response Unexpected 'G'. What could this mean? I have been dumping the variable as you can see, it's commented, but can't understand why this is occuring.

Any clues?

public function findAction(Request $request)
{
    $form = $this->createFormBuilder(null, ['csrf_protection' => false])
        ->add('Title', TextType::class)
        ->add('Search', SubmitType::class)
        ->getForm();

    $form->handleRequest($request);

    if($form->isValid()){
        $json = file_get_contents("https://www.googleapis.com/books/v1/volumes?q=".$form->get('Title')->getData());
        $response = json_decode($json, true);

        if(array_key_exists('items', $response)){
            return $this->render('BlogsiteBooksBundle:Pages:results.html.twig', [
                'items' => $response['items']
            ]);
        } else {
            return new Response('Google did not have any items', 400);
        }
    }

    //var_dump($request);

    return new Response('Google Book Not Found', 404);
}

Solution

  • Your request is not related to the form, build the form using Symfony form component in the controller, and manually in the twig, then parameters names does not match. The $form->handleRequest($request); can't find the title, because expect a parameter called form[Title] and you are passing only Title.

    Solutions:

    1 - Submit manually all given parameters in the query

    Change:

    $form->handleRequest($request);
    

    For this:

    $form->submit($request->query->all());
    

    2 - Change the name of the input to match with symfony expected name and the method used should be POST:

    <form action="app_dev.php/find" method="post">
            <input type="text" name="form[Title]" id="Title" value="">
            <input type="submit" value="Search">
        </form>
    

    3 - Render your form using twig form to avoid this problems

    Controller:

        /**
         * @Route(name="find", path="/find")
         */
        public function findAction(Request $request)
        {
            $form = $this->createFormBuilder(null)
                         ->add('Title', TextType::class)
                         ->add('Search', SubmitType::class)
                         ->getForm();
    
            $form->handleRequest($request);
    
            if ($form->isSubmitted() && $form->isValid()) {
                $json = file_get_contents("https://www.googleapis.com/books/v1/volumes?q=".$form->get('Title')->getData());
                $response = json_decode($json, true);
                if (array_key_exists('items', $response)) {
                    return $this->render(
                        'BlogsiteBooksBundle:Pages:results.html.twig',
                        [
                            'items' => $response['items'],
                        ]
                    );
                } else {
                    $form->addError(new FormError('Google did not have any items'));
                }
            }
    
            return $this->render('find.html.twig', ['form' => $form->createView()]);
        }
    

    View find.html.twig:

    {{ form(form) }}
    

    Note: each point is a possible solution, use only one of them, the third is the recommended for simple Symfony forms.