RyukShi
RyukShi

Reputation: 93

Question about null coalescing operator (??) and rendering twig view

I have some question about null coalescing operator (??) to rendering a twig view. So I would like to set the form to null if the user is not logged. I give you my PHP controller method code :

    #[Route('/{id}', name: 'app_recipe_show', methods: ['GET', 'POST'], requirements: ['id' => '[1-9]\d*'])]
    public function show(Recipe $recipe, UserRepository $userRepository, Request $request): Response
    {
        $user = $this->getUser();
        // If the user is logged
        if ($user) {
            // If the user is the cooker of the recipe
            $isCooker = $user->getId() === $recipe->getCooker()->getId();

            // If the recipe is in the user's favorites
            $isFavorite = $user->getFavorites() !== null && in_array($recipe->getId(), $user->getFavorites(), true);

            // create form to add/remove the recipe to the user's favorites
            $favoriteForm = $this->createFormBuilder()
                ->add('submit', SubmitType::class, ['label' => ($isFavorite) ? 'Remove from favorites' : 'Add to favorites'])
                ->setMethod('POST')
                ->getForm();

            $favoriteForm->handleRequest($request);

            if ($favoriteForm->isSubmitted() && $favoriteForm->isValid()) {
                if ($isFavorite) {
                    // remove the recipe from the user's favorites
                    $user->removeRecipeFromFavorites($recipe->getId());
                } else {
                    // add the recipe to the user's favorites
                    $user->addRecipeToFavorites($recipe->getId());
                }
                // persist the user and flush it
                $userRepository->add($user, true);
                // redirect to the recipe show page
                return $this->redirectToRoute(
                    'app_recipe_show',
                    ['id' => $recipe->getId()],
                    Response::HTTP_SEE_OTHER
                );
            }
        }

        return $this->render('recipe/show.html.twig', [
            'recipe' => $recipe,
            'is_cooker' => $isCooker ?? false,
            'is_favorite' => $isFavorite ?? false,
            // null coalescing operator (??) set the form to null if the user is not logged
            'favorite_form' => $favoriteForm->createView() ?? null,
        ]);
    }

And I have an error telling that the variable $favoriteForm is Undefined. What's normal ! How do I do that ?

Upvotes: 1

Views: 380

Answers (1)

msg
msg

Reputation: 8161

Yes, that behaviour is normal. That's because ?? is evaluating the result of createView(), but it cannot be executed because $favoriteForm isn't defined: it's created conditionally only if there's a user logged in.

If you are using php >= 8.0, you'd want to use the nullsafe operator instead:

'favorite_form' => $favoriteForm?->createView(),

If you are in a lower version, you'd have to resort to a more terse construct:

'favorite_form' => isset($favoriteForm) ? $favoriteForm->createView() : null,

Also, as it's used it doesn't make much sense, because according to the documentation:

The null coalescing operator (??) [...] returns its first operand if it exists and is not null; otherwise it returns its second operand.

If createView() returned null, coalescing to null would be a no-op.

Upvotes: 2

Related Questions