WEBVTT

NOTE Created by CaptionSync from Automatic Sync Technologies www.automaticsync.com

00:00:03.236 --> 00:00:04.336 align:middle
Remove the link.

00:00:06.276 --> 00:00:10.216 align:middle
In base.html.twig, we already
have a few JavaScript files

00:00:10.216 --> 00:00:11.946 align:middle
that are included on every page.

00:00:12.246 --> 00:00:15.986 align:middle
But now, I want to include some
JavaScript on just this page -

00:00:16.356 --> 00:00:18.056 align:middle
I don't need this stuff everywhere.

00:00:18.806 --> 00:00:22.046 align:middle
Remember from earlier that those script
tags live in a javascripts block.

00:00:22.806 --> 00:00:23.766 align:middle
Hey, that's perfect!

00:00:23.886 --> 00:00:26.496 align:middle
In the child template, we
can override that block:

00:00:26.496 --> 00:00:29.676 align:middle
{% block javascripts %} then {% endblock %}:

00:00:31.776 --> 00:00:35.716 align:middle
Now, whatever JS we put here will
end up at the bottom of the layout.

00:00:35.716 --> 00:00:36.886 align:middle
Perfect, right?

00:00:37.166 --> 00:00:39.266 align:middle
No, not perfect!

00:00:39.666 --> 00:00:43.036 align:middle
When you override blocks,
you override them completely.

00:00:43.606 --> 00:00:47.666 align:middle
With this code, it will completely replace
the other scripts in the base template.

00:00:48.316 --> 00:00:49.686 align:middle
I don't want that!

00:00:49.686 --> 00:00:52.936 align:middle
I really want to append content to this block.

00:00:53.616 --> 00:00:56.846 align:middle
The secret awesome solution to
this is the parent() function:

00:00:57.376 --> 00:00:59.756 align:middle
This prints all of the content
from the parent block,

00:00:59.896 --> 00:01:02.926 align:middle
and then we can put our cool stuff below that.

00:01:03.596 --> 00:01:08.976 align:middle
Here's the goal: add some JavaScript that will
make an AJAX request to the notes API endpoint

00:01:09.196 --> 00:01:12.786 align:middle
and use that to render them with
the same markup we had before.

00:01:13.596 --> 00:01:15.256 align:middle
We'll use ReactJS to do this.

00:01:15.646 --> 00:01:16.406 align:middle
It's powerful...

00:01:16.526 --> 00:01:19.776 align:middle
and super fun, but if it's
new to you, don't worry.

00:01:20.216 --> 00:01:23.026 align:middle
We're not going to learn it
now, just preview it to see how

00:01:23.026 --> 00:01:25.636 align:middle
to get our API working with
a JavaScript frontend.

00:01:25.736 --> 00:01:30.506 align:middle
First, include three external
script tags for React itself.

00:01:30.506 --> 00:01:35.406 align:middle
Next, I'm going to include one more script
tag that points to a file in our project:

00:01:37.976 --> 00:01:42.346 align:middle
notes.react.js: Let's check that file out!

00:01:42.766 --> 00:01:52.236 align:middle
Remember, it's in web/js/notes.react.js:
This is a small ReactJS app that uses our API

00:01:52.396 --> 00:01:57.076 align:middle
to build all of the same markup that we
had on the page before, but dynamically.

00:01:57.546 --> 00:01:59.896 align:middle
It uses jQuery to make the AJAX call:

00:02:01.476 --> 00:02:07.526 align:middle
But I have a hardcoded URL right
now - /genus/octopus/notes.

00:02:08.146 --> 00:02:10.986 align:middle
Obviously, that's a problem, and lame.

00:02:11.366 --> 00:02:12.756 align:middle
But ignore it for a second.

00:02:13.546 --> 00:02:16.256 align:middle
Back in the template, we need
to start up the ReactJS app.

00:02:16.256 --> 00:02:21.306 align:middle
Add a script tag with type="text/babel"
- that's a React thing.

00:02:23.306 --> 00:02:28.286 align:middle
To boot the app, add ReactDOM.render:
PhpStorm is not going

00:02:28.286 --> 00:02:30.486 align:middle
to like how this looks, but ignore it.

00:02:31.246 --> 00:02:39.336 align:middle
Render the NoteSection into
document.getElementById('js-notes-wrapper'):

00:02:41.506 --> 00:02:46.096 align:middle
Back in the HTML area, clear things
out and add an empty div with this id:

00:02:46.096 --> 00:02:48.926 align:middle
Everything will be rendered here.

00:02:51.136 --> 00:02:51.966 align:middle
Ya know what?

00:02:51.966 --> 00:02:52.766 align:middle
I think we should try it.

00:02:53.256 --> 00:02:53.946 align:middle
Refresh.

00:02:55.376 --> 00:02:56.766 align:middle
It's alive!

00:02:57.336 --> 00:03:00.476 align:middle
It happened quickly, but
this is loading dynamically.

00:03:00.836 --> 00:03:05.346 align:middle
In fact, I added some simple magic so that
it checks for new comments every two seconds.

00:03:06.036 --> 00:03:08.086 align:middle
Let's see if it'll update without refreshing.

00:03:08.086 --> 00:03:13.806 align:middle
In the controller, remove one of the
notes - take out AquaWeaver in the middle.

00:03:14.646 --> 00:03:15.566 align:middle
Back to the browser!

00:03:17.076 --> 00:03:18.596 align:middle
Boom! It's gone.

00:03:18.926 --> 00:03:19.636 align:middle
Now put it back.

00:03:22.136 --> 00:03:22.666 align:middle
There it is!

00:03:22.776 --> 00:03:26.276 align:middle
So, really cool stuff.

00:03:26.276 --> 00:03:29.476 align:middle
But... we still have that hardcoded URL.

00:03:29.816 --> 00:03:32.516 align:middle
That's still lame, and a problem.

00:03:33.436 --> 00:03:38.386 align:middle
How you fix this will depend on if you're
using AngularJS, ReactJS or something else.

00:03:38.756 --> 00:03:43.436 align:middle
But the idea is the same: we need to
pass the dynamic value into JavaScript.

00:03:44.136 --> 00:03:51.776 align:middle
Change the URL to this.props.url: This means
that we will pass a url property to NoteSection.

00:03:51.776 --> 00:03:55.766 align:middle
Since we create that in the Twig
template, we'll pass it in there.

00:03:55.886 --> 00:03:59.366 align:middle
First, we need to get the
URL to the API endpoint.

00:04:00.216 --> 00:04:02.976 align:middle
Add var notesUrl = ''.

00:04:03.666 --> 00:04:07.576 align:middle
Inside, generate the URL with twig using path().

00:04:07.576 --> 00:04:16.076 align:middle
Pass it genus_show_notes and the genusName set
to name: Yes, this is Twig inside of JavaScript.

00:04:16.076 --> 00:04:19.826 align:middle
And yes, I know it can feel a little crazy.

00:04:19.826 --> 00:04:27.536 align:middle
Finally, pass this into React as a prop
using url={notesUrl}: Try that out.

00:04:29.476 --> 00:04:31.706 align:middle
It still works very nicely.

00:04:32.316 --> 00:04:36.626 align:middle
Congrats on making it this
far: it means you're serious!

00:04:37.486 --> 00:04:41.086 align:middle
We've just started, but we've
already created a rich HTML page

00:04:41.136 --> 00:04:44.746 align:middle
and an API endpoint to fuel
some sweet JavaScript.

00:04:44.746 --> 00:04:48.336 align:middle
And we're just starting to
scratch the surface of Symfony.

00:04:48.336 --> 00:04:52.836 align:middle
What about talking to a database,
using forms, setting up security

00:04:52.836 --> 00:04:55.106 align:middle
or handling API input and validation?

00:04:55.836 --> 00:04:59.076 align:middle
How and why should you register
your own services?

00:04:59.076 --> 00:05:00.846 align:middle
And what are event listeners?

00:05:00.846 --> 00:05:05.146 align:middle
The answers to these will make
you truly dangerous not just

00:05:05.146 --> 00:05:07.586 align:middle
in Symfony, but as a programmer in general.

00:05:07.696 --> 00:05:12.346 align:middle
See you on the next challenge.

