Hi, I went through the tutorial and it showes me the correct data, but not formated, like: {"notes":[{"id":1,"username":"AquaPelham","avatarUri":"\/images\/leanna.jpeg","note":"Octopus asked me a riddle, outsmarted me","date":"Dec. 10, 2015"},{"id":2,"username":"AquaWeaver","avatarUri":"\/images\/ryan.jpeg","note":"I counted 8 legs... as they wrapped around me","date":"Dec. 1, 2015"},{"id":3,"username":"AquaPelham","avatarUri":"\/images\/leanna.jpeg","note":"Inked!","date":"Aug. 20, 2015"}]} All in one line, is it ok?
To work just fine, I had to add after the namespace "use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;" and "use Symfony\Component\HttpFoundation\JsonResponse;". I suppose it's the fault of my IDE but everthing else was working just fine.
I suppose you're right, it's due to the IDE. You have to allow your IDE *autocomplete* the class name, i.e. you need to write a part of the class name and then choose it from the drop-down list. Then your IDE should add this namespace after the "namespace" declaration for you.
Hi, weaverryan ! Principally I'd like to organize my dependencies in a more meaningful way by using the require-dev key in composer.json for dev-only dependencies. As I see in the tutorial code you place the sensio/generator-bundle under require-dev and it's fine. However, if I try this in my project, my deployment explodes with errors, although I'd expect it to work, as composer install has the --dev option as default. So it should install all dependencies under require AND require-dev anyway. I guess I've just not understood it completely :/
I think I know the issue :). But first, it's *more* important that you only enable "dev" bundles in the dev/test environments in AppKernel than adding libraries to require-dev. Making sure a bundle doesn't get loaded in "prod" if it's not needed actually makes your container smaller and gives you a smaller memory footprint. But require-dev basically just makes your filesystem footprint smaller - which doesn't have much impact on performance.
Now, I'm guessing that your deploy explodes on "composer install" - is that correct? If you *don't* install SensioGeneratorBundle (--no-dev), then you *must* run all app/console commands with --env=prod. You cannot use the "dev" environment at all anymore - as SensioGeneratorBundle needs to be included in AppKernel in dev. When you run composer install, it runs a few app/console commands *for* you, and it runs them in the dev environment by default. To make these commands run in the "prod" environment, you can run "export SYMFONY_ENV=prod" to set an environment variable. More details here: http://symfony.com/doc/curr...
For me, this is enough of a headache that I usually *do* install dev dependencies on the production server.
Welcome to Symfony :). I can definitely help you to start debugging this guy! This error means that Symfony looked at all of your routes (i.e. your @Route annotations), but could not find a route that matched the URL /genus/octopus/notes. So probably, there is a problem with the @Route annotation that we added here: https://knpuniversity.com/screencast/symfony/json-api#creating-api-endpoints
Also, it might be helpful to see what routes Symfony does know of. Try running this command:
php bin/console debug:router
Do you see a route whose path is /genus/octopus/notes (probably not, based on the error). This output might help you know what routes Symfony is (and is not) seeing!
Hi, after the modification for creating the second page, when I go to the first page I get this error $message .= sprintf(' (from "%s")', $referer); } throw new NotFoundHttpException($message, $e); } catch (MethodNotAllowedException $e) { $message = sprintf('No route found for "%s %s": Method Not Allowed (Allow: %s)', $request->getMethod(), $request->getPathInfo(), implode(', ', $e->getAllowedMethods()));
I did the command to clear the cache, but It's still not working. No error for the second page with json
When a "MethodNotAllowedException" is thrown it's because you are trying to access a route with an invalid method, like trying to do a POST request to the "/genus/{genusName}/notes" route Can you show me how looks like your GenusController ?
Ok, below there is the whole code of the file GenusController.php. Thanks in advance.
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Response;
class GenusController extends Controller { /** * @Route("/genus/{genusName}") */ public function showAction($genusName) {
I don't know why, but now is working. I've just cut the section notes in the show.html.twig. I did the same before, but the previous time I deleted also the empty row between the two section tag (as shown in the video). The empty row is the only thing I made different, but maybe I made some other errors when deleting that row. Now it's fine, thanks for the quick reply.
Is it okay if when trying to access my http://localhost:8000/genus/octopus I get error saying: Variable "notes" does not exist in genus/show.html.twig at line 25
That's bad. It means you try to use variable notes didn't passed into the template. Probably you forgot to pass it in a controller's action which render this template like:
public function someAction()
{
// some code
return $this->render('genus/show.html.twig', [
'notes' => $notes,
// other variables
]);
}
Ah, let's debug this thing! PhpStorm could help with it, right click on the project, choose "Find in path" item in drop down menu and search for "show.html.twig". PhpStorm finds all places where you use this template. Then ensure you pass that "notes" variable to this template in all places where you render / use it. Of course, you should exclude cache directory. BTW, don't forget to clear cache as well after any changes, especially for prod env.
I had a similar issue as others. Symfony was not able to find route /genus/{genusName} anymore. notes route was working. I just continue to follow your instruction in the next chapter and the issue resolved by itself. I wonder if it is a cache issue as you mentioned above.
Is there any special way to clear cash in phpStorm or in symfony?
Yes, Symfony has a console command to clear its cache - execute the next command in your terminal:
# to clear the cache for dev environment:
$ bin/console cache:clear
# or to clear the cache for prod environment (or any other environment you have, just type it instead of prod):
$ bin/console cache:clear --env=prod
Thanks ! I feel very lost... Is there any other lessons that a beginner should follow before this course (except the PHP POO part that I have already did )?
Not a stupid question :). There is no reason - both would work just fine. Typically, when I am returning a "list" of things (like a list of notes), I put them under a key. This would allow you later to add other properties more easily, in case you want to return notes and something else. But technically speaking, there's no reason - but it's a good idea!
I don't what happened, but my output is still the same after using json_encode:
{"notes":[{"id":1,"username":"AquaPelham","avatarUri":"\/images\/leanna.jpeg","note":"Octopus asked me a riddle, outsmarted me","date":"Dec. 10, 2015"},{"id":2,"username":"AquaWeaver","avatarUri":"\/images\/ryan.jpeg","note":"I counted 8 legs... as they wrapped around me","date":"Dec. 1, 2015"},{"id":3,"username":"AquaPelham","avatarUri":"\/images\/leanna.jpeg","note":"Inked!","date":"Aug. 20, 2015"}]}
Actually, this JSON output looks perfect! You *should* be getting exactly this after returning new Response(json_encode($data)) or new JsonResponse($data).
They are talking about the formatting of the output not the output itself. For anyone else with the issue, install a browser extension (or plug in). Just search for your browser + "json formatter".
I am trying to make a quick api with symfony as backend, and a completely separate front end (angular1) talking to the symfony api. I am not sure how to get rid of the cross origin issue. Could you give me some pointer on how to set up the cors so that I can use the api from the front end app (javascript. no php, no twig) in another domain?
Sure! I typically use https://github.com/nelmio/N.... It works really nicely to return the necessary headers from your API so that JavaScript can get passed the CORS issue. Of course, another solution (which just may not be possible in your situation) is to keep the two sites under the same domain - then CORS isn't a problem.
Thank you for your reply. I struggled for many hours, but yes I used the nelmio cors bundle thingy, and now it is working. Still not understanding 100% how I made it work with the nelmio settings, but good enough for now.
55 Comments
nice work bro keep up (y) :)
Hi,
I went through the tutorial and it showes me the correct data, but not formated, like:
{"notes":[{"id":1,"username":"AquaPelham","avatarUri":"\/images\/leanna.jpeg","note":"Octopus asked me a riddle, outsmarted me","date":"Dec. 10, 2015"},{"id":2,"username":"AquaWeaver","avatarUri":"\/images\/ryan.jpeg","note":"I counted 8 legs... as they wrapped around me","date":"Dec. 1, 2015"},{"id":3,"username":"AquaPelham","avatarUri":"\/images\/leanna.jpeg","note":"Inked!","date":"Aug. 20, 2015"}]}
All in one line, is it ok?
Hi Konrad!
Yep, it's ok :). Technically, my output also has no spaces, but I have a plugin for my browser - JSONView - which formats it "pretty" for me.
Cheers!
Would've been better to mention it, thought I made a mistake.
Nice pugin. I've already thought that I made a mistake :D
Thanks for asking, i had the same is question (y)
To work just fine, I had to add after the namespace "use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;" and "use Symfony\Component\HttpFoundation\JsonResponse;".
I suppose it's the fault of my IDE but everthing else was working just fine.
Hey Antonio,
I suppose you're right, it's due to the IDE. You have to allow your IDE *autocomplete* the class name, i.e. you need to write a part of the class name and then choose it from the drop-down list. Then your IDE should add this namespace after the "namespace" declaration for you.
Cheers!
can it be that this track isn't valid for 3.4?
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
is deprecated, and bin/console Debug:router doesn't show GET as method for the route :/
Hey Sammy F.
This course is totally valid for Symfony 3.4 but you will see more deprecated messages.
> bin/console Debug:router doesn't show GET as method for the route
What do you see when executing it?
Cheers!
It's the same for me. The method is ANY instead of GET.
Hey Jon,
Try to set the method on "@Route" annotation, like:
Then, clear the cache and rerun the same command:
$ bin/console debug:router
Does it works for you? Do you see the GET instead of ANY now?
Cheers!
Just as an fyi, you also need PHP Annotations plugin for the Annotation auto-complete to work in PHPStorm.
Yes, good tip! I completely forgot to mention that in the Phpstorm chapter :)
That tripped me up as well.
Hi, weaverryan ! Principally I'd like to organize my dependencies in a more meaningful way by using the require-dev key in composer.json for dev-only dependencies. As I see in the tutorial code you place the sensio/generator-bundle under require-dev and it's fine. However, if I try this in my project, my deployment explodes with errors, although I'd expect it to work, as composer install has the --dev option as default. So it should install all dependencies under require AND require-dev anyway. I guess I've just not understood it completely :/
Hey there!
I think I know the issue :). But first, it's *more* important that you only enable "dev" bundles in the dev/test environments in AppKernel than adding libraries to require-dev. Making sure a bundle doesn't get loaded in "prod" if it's not needed actually makes your container smaller and gives you a smaller memory footprint. But require-dev basically just makes your filesystem footprint smaller - which doesn't have much impact on performance.
Now, I'm guessing that your deploy explodes on "composer install" - is that correct? If you *don't* install SensioGeneratorBundle (--no-dev), then you *must* run all app/console commands with --env=prod. You cannot use the "dev" environment at all anymore - as SensioGeneratorBundle needs to be included in AppKernel in dev. When you run composer install, it runs a few app/console commands *for* you, and it runs them in the dev environment by default. To make these commands run in the "prod" environment, you can run "export SYMFONY_ENV=prod" to set an environment variable. More details here: http://symfony.com/doc/curr...
For me, this is enough of a headache that I usually *do* install dev dependencies on the production server.
I hope that helps!
Hi! How i can set JSON_UNESCAPED_UNICODE and JSON_UNESCAPED_SLASHES to JsonResponse?
Hey Yuri!
It should be like this:
Here's some more info, above the encodingOptions property in that class: https://github.com/symfony/symfony/blob/1b6b08cf0babd52390ed50f95648f1cf58f8f67d/src/Symfony/Component/HttpFoundation/JsonResponse.php#L32
Hope that helps!
Nice! Thank you!
Yo Dan!
Welcome to Symfony :). I can definitely help you to start debugging this guy! This error means that Symfony looked at all of your routes (i.e. your @Route annotations), but could not find a route that matched the URL /genus/octopus/notes. So probably, there is a problem with the @Route annotation that we added here: https://knpuniversity.com/screencast/symfony/json-api#creating-api-endpoints
Also, it might be helpful to see what routes Symfony does know of. Try running this command:
Do you see a route whose path is /genus/octopus/notes (probably not, based on the error). This output might help you know what routes Symfony is (and is not) seeing!
Let us know if this helps! Cheers!
Hi, after the modification for creating the second page, when I go to the first page I get this error
$message .= sprintf(' (from "%s")', $referer); } throw new NotFoundHttpException($message, $e); } catch (MethodNotAllowedException $e) { $message = sprintf('No route found for "%s %s": Method Not Allowed (Allow: %s)', $request->getMethod(), $request->getPathInfo(), implode(', ', $e->getAllowedMethods()));
I did the command to clear the cache, but It's still not working.
No error for the second page with json
Hey Josk
When a "MethodNotAllowedException" is thrown it's because you are trying to access a route with an invalid method, like trying to do a POST request to the "/genus/{genusName}/notes" route
Can you show me how looks like your GenusController ?
Have a nice day
Ok, below there is the whole code of the file GenusController.php. Thanks in advance.
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class GenusController extends Controller
{
/**
* @Route("/genus/{genusName}")
*/
public function showAction($genusName)
{
return $this->render('genus/show.html.twig', [
'name' => $genusName,
]);
}
/**
* @Route("/genus/{genusName}/notes")
* @Method("GET")
*/
public function getNotesAction()
{
$notes = [
['id' => 1, 'username' => 'AquaPelham', 'avatarUri' => '/images/leanna.jpeg', 'note' => 'Octopus asked me a riddle, outsmarted me', 'date' => 'Dec. 10, 2015'],
['id' => 2, 'username' => 'AquaWeaver', 'avatarUri' => '/images/ryan.jpeg', 'note' => 'I counted 8 legs... as they wrapped around me', 'date' => 'Dec. 1, 2015'],
['id' => 3, 'username' => 'AquaPelham', 'avatarUri' => '/images/leanna.jpeg', 'note' => 'Inked!', 'date' => 'Aug. 20, 2015'],
];
$data=[
'notes'=>$notes,
];
return new Response(json_encode($data));
}
}
I don't know why, but now is working. I've just cut the section notes in the show.html.twig. I did the same before, but the previous time I deleted also the empty row between the two section tag (as shown in the video). The empty row is the only thing I made different, but maybe I made some other errors when deleting that row.
Now it's fine, thanks for the quick reply.
Hmm, your routes looks good to me, can you show me the exception and stack trace please ?
Luckly I don't have it anymore because is working now, but the error message was about missing route to genusname/GET
Hey Josk,
Ah, probably the problem was in cache, or just a simple misprint. Anyway, glad you got it working!
Cheers!
Is it okay if when trying to access my http://localhost:8000/genus/octopus I get error saying: Variable "notes" does not exist in genus/show.html.twig at line 25
Hey Viktor,
That's bad. It means you try to use variable
notesdidn't passed into the template. Probably you forgot to pass it in a controller's action which render this template like:Check that and let me know if it helped.
Cheers!
I have the same problem and it doesn't help me...
Hey Zoe,
Ah, let's debug this thing! PhpStorm could help with it, right click on the project, choose "Find in path" item in drop down menu and search for "show.html.twig". PhpStorm finds all places where you use this template. Then ensure you pass that "notes" variable to this template in all places where you render / use it. Of course, you should exclude cache directory. BTW, don't forget to clear cache as well after any changes, especially for prod env.
Cheers!
Hi, Victor
I had a similar issue as others. Symfony was not able to find route /genus/{genusName} anymore. notes route was working.
I just continue to follow your instruction in the next chapter and the issue resolved by itself. I wonder if it is a cache issue as you mentioned above.
Is there any special way to clear cash in phpStorm or in symfony?
Your help is appreciated.
Hey Nobuyuki,
Yes, Symfony has a console command to clear its cache - execute the next command in your terminal:
Cheers!
Hi, Victor
Excellent! Thank you!
Just minor note, I think cache:clear instead of clear:cache. It works now. Thanks! =)
Ah, yes! it's my fault... Thanks for noticing me, I'll edit my comment )
Thanks ! I feel very lost... Is there any other lessons that a beginner should follow before this course (except the PHP POO part that I have already did )?
Oh, did you confuse due to my answer? Or was this tutorial hard for you? Tell us what was the hardest part for you in this course.
I think this is actually normal, because in the video we deleted the variable called $notes from the showAction method.
Why use $data = ['notes' => $notes]; instead of just returning notes???
Sorry if is a stupid question. I had never usen Json before.
Not a stupid question :). There is no reason - both would work just fine. Typically, when I am returning a "list" of things (like a list of notes), I put them under a key. This would allow you later to add other properties more easily, in case you want to return notes and something else. But technically speaking, there's no reason - but it's a good idea!
Hi,
I don't what happened, but my output is still the same after using json_encode:
{"notes":[{"id":1,"username":"AquaPelham","avatarUri":"\/images\/leanna.jpeg","note":"Octopus asked me a riddle, outsmarted me","date":"Dec. 10, 2015"},{"id":2,"username":"AquaWeaver","avatarUri":"\/images\/ryan.jpeg","note":"I counted 8 legs... as they wrapped around me","date":"Dec. 1, 2015"},{"id":3,"username":"AquaPelham","avatarUri":"\/images\/leanna.jpeg","note":"Inked!","date":"Aug. 20, 2015"}]}
Any recommendations, thanks!
Hi!
Actually, this JSON output looks perfect! You *should* be getting exactly this after returning new Response(json_encode($data)) or new JsonResponse($data).
Is there an issue I'm missing?
Cheers!
I had same output as hanthuy had too , but after installing JSONView on firefox all is fine!
Yeah, your result is really nice with line by line, but I'm not. Is there any differences? Thanks,
{
- note: [
xxxxxx
]
}
Updated: I also think that's the reason why my notes doesn't appear in the next video although I added the {% block javascripts %} to show.html.twig
They are talking about the formatting of the output not the output itself. For anyone else with the issue, install a browser extension (or plug in). Just search for your browser + "json formatter".
Hi, KnpUniversity
I am trying to make a quick api with symfony as backend, and a completely separate front end (angular1) talking to the symfony api.
I am not sure how to get rid of the cross origin issue. Could you give me some pointer on how to set up the cors so that I can use the api from the front end app (javascript. no php, no twig) in another domain?
Thanks,
Noby
Hey Noby!
Sure! I typically use https://github.com/nelmio/N.... It works really nicely to return the necessary headers from your API so that JavaScript can get passed the CORS issue. Of course, another solution (which just may not be possible in your situation) is to keep the two sites under the same domain - then CORS isn't a problem.
Cheers!
Yo, Ryan
Thank you for your reply. I struggled for many hours, but yes I used the nelmio cors bundle thingy, and now it is working. Still not understanding 100% how I made it work with the nelmio settings, but good enough for now.
Cheers,
Noby
Yes, awesome! If you have any questions, let me know!
Keep up the good work!
"Houston: no signs of life"
Start the conversation!