WEBVTT

00:00:01.056 --> 00:00:02.526 align:middle
Una de las funcionalidades en nuestro sitio...

00:00:02.766 --> 00:00:04.066 align:middle
la cual aun no funciona...

00:00:04.306 --> 00:00:07.656 align:middle
es la de votar a favor o en contra
en las respuestas de las preguntas.

00:00:08.456 --> 00:00:13.136 align:middle
Eventualmente, cuando hagas click arriba o abajo,
esto hará un request tipo AJAX

00:00:13.216 --> 00:00:15.716 align:middle
a una ruta de una API que vamos a crear.

00:00:16.236 --> 00:00:21.186 align:middle
Esa ruta va a guardar el voto en la base de
datos y va a responder con un JSON

00:00:21.376 --> 00:00:27.056 align:middle
que contendrá el nuevo total de votos y así
nuestro JavaScript podrá actualizar el contador.

00:00:28.106 --> 00:00:29.986 align:middle
Aún no tenemos una base de datos en nuestra aplicación,

00:00:30.366 --> 00:00:33.626 align:middle
pero estamos listos para construir todas las otras
partes de esta funcionalidad.

00:00:34.866 --> 00:00:40.616 align:middle
Comencemos por crear una ruta tipo JSON para
la API a la cual accederemos con AJAX

00:00:40.826 --> 00:00:43.276 align:middle
cuando el usuario vote en una respuesta arriba o abajo.

00:00:44.106 --> 00:00:48.256 align:middle
Podríamos crear esto en QuestionController
como un nuevo método.

00:00:48.666 --> 00:00:54.066 align:middle
Pero como esta ruta en realidad trabaja con un
"comment", vamos a crear un nuevo controlador.

00:00:56.106 --> 00:00:57.606 align:middle
Llámalo CommentController.

00:00:58.876 --> 00:01:04.306 align:middle
Como la vez pasada, vamos a escribir
extends AbstractController y presionar tab

00:01:04.476 --> 00:01:08.926 align:middle
para que PhpStorm autocomplete esto y agregue
el import en la parte de arriba.

00:01:08.926 --> 00:01:12.286 align:middle
Al extender de esta clase nos brinda
métodos de atajo...

00:01:12.376 --> 00:01:14.766 align:middle
y me encantan los atajos!

00:01:14.766 --> 00:01:16.836 align:middle
Dentro, crea una función pública.

00:01:17.286 --> 00:01:18.506 align:middle
Puede tener cualquier nombre...

00:01:18.946 --> 00:01:20.666 align:middle
que tal commentVote().

00:01:23.006 --> 00:01:27.406 align:middle
Agrega la ruta arriba: /**, luego @Route.

00:01:28.126 --> 00:01:34.236 align:middle
Autocompleta la del componente Routing para
que asi PhpStorm agregue el import.

00:01:34.336 --> 00:01:43.606 align:middle
Para la URL, que tal /comments/{id}
- esto eventualmente será el id

00:01:43.606 --> 00:01:49.276 align:middle
del comentario específico en la
base de datos - /vote/{direction},

00:01:51.136 --> 00:01:55.076 align:middle
donde {direction} será cualquiera de
las palabras arriba o abajo.

00:01:56.106 --> 00:02:02.556 align:middle
y como tenemos estos dos comodines, podemos
agregar dos argumentos: $id y $direction.

00:02:03.876 --> 00:02:10.446 align:middle
Empezaré con un comentario: el $id será súper
importante después cuando tengamos una base de datos...

00:02:10.586 --> 00:02:12.846 align:middle
pero no lo vamos a usar por ahora.

00:02:13.716 --> 00:02:16.836 align:middle
Sin una base de datos, vamos a simular la lógica.

00:02:16.836 --> 00:02:24.106 align:middle
Si $direction == 'up', entonces normalmente
guardaríamos el voto a favor en la base de datos

00:02:24.346 --> 00:02:26.636 align:middle
y consultaríamos el nuevo total de votos.

00:02:27.346 --> 00:02:34.396 align:middle
En vez de eso, escribe $currentVoteCount = rand(7, 100).

00:02:35.286 --> 00:02:38.586 align:middle
El conteo de votos está escrito directamente en
el template con un total de 6.

00:02:38.666 --> 00:02:44.496 align:middle
Así que esto hará que el nuevo conteo de votos
parezca ser un nuevo número mayor que este.

00:02:45.336 --> 00:02:53.096 align:middle
En el else, haz lo opuesto: un
número aleatorio entre 0 y 5.

00:02:53.096 --> 00:02:56.926 align:middle
Si, esto será mucho más interesante
cuando tengamos una base de datos,

00:02:57.156 --> 00:02:59.516 align:middle
pero va a funcionar muy bien para nuestro propósito.

00:03:00.776 --> 00:03:05.066 align:middle
La pregunta ahora es: después de "Guardar"
el voto en la base de datos,

00:03:05.376 --> 00:03:07.816 align:middle
que debería de retornar el controlador?

00:03:08.656 --> 00:03:11.426 align:middle
Bueno, probablemente debería retornar un JSON...

00:03:11.806 --> 00:03:18.376 align:middle
y sé que quiero incluir el nuevo conteo en la
respuesta para que nuestro JavaScript pueda utilizarlo

00:03:18.376 --> 00:03:20.916 align:middle
y actualizar el número de votos.

00:03:20.966 --> 00:03:24.526 align:middle
Así que... como regresamos un JSON?

00:03:25.356 --> 00:03:30.976 align:middle
Recuerda: nuestro único trabajo en un controlador
es retornar un objeto de tipo Symfony Response.

00:03:31.716 --> 00:03:38.216 align:middle
JSON no es nada más que una respuesta cuyo
contenido es una cadena JSON en vez de HTML.

00:03:39.036 --> 00:03:45.086 align:middle
Así que podemos poner: return new Response()
con json_encode() con algún dato.

00:03:45.796 --> 00:03:51.986 align:middle
Pero! en vez de eso, return new
JsonResponse() - autocompleta esto

00:03:52.116 --> 00:03:54.436 align:middle
para que PhPStorm agregue el import.

00:03:55.216 --> 00:03:57.826 align:middle
Pasa un array con los datos que queremos.

00:03:58.416 --> 00:04:01.956 align:middle
Que tal pasar la llave votes con $currentVoteCount.

00:04:02.796 --> 00:04:05.816 align:middle
Ahora... tal vez estés pensando: Ryan!

00:04:06.186 --> 00:04:10.476 align:middle
Te la pasas diciendo que debemos retornar un
objeto Response...

00:04:10.476 --> 00:04:13.356 align:middle
y acabas de retornar algo diferente.

00:04:13.696 --> 00:04:14.916 align:middle
Esto es una locura!

00:04:15.036 --> 00:04:16.506 align:middle
Es un punto válido.

00:04:17.056 --> 00:04:22.026 align:middle
Pero! si presionas Command or Ctrl y das
click en la clase JsonResponse,

00:04:22.666 --> 00:04:26.776 align:middle
vas a aprender que JsonResponse hereda de Response.

00:04:27.406 --> 00:04:31.946 align:middle
Esta clase no es nada más que un atajo para
crear respuestas tipo JSON:

00:04:32.706 --> 00:04:39.416 align:middle
esto hace el JSON encode a los datos que le pasamos y
se asegura que la cabecera Content-Type sea asignada

00:04:39.416 --> 00:04:46.846 align:middle
a application/json, la cual ayuda a las librerías
AJAX a entender que estamos regresando un JSON.

00:04:46.986 --> 00:04:52.496 align:middle
Así que... ah! Probemos nuestra nueva y brillante
ruta de la API!

00:04:53.006 --> 00:04:58.866 align:middle
Copia la URL, abre un nueva nueva pestaña en el
navegador, pega y llena los comodines:

00:04:59.246 --> 00:05:02.236 align:middle
que tal 10 para el id y para el voto "up".

00:05:02.986 --> 00:05:03.696 align:middle
Presiona enter.

00:05:04.276 --> 00:05:06.236 align:middle
Hola ruta JSON!

00:05:06.856 --> 00:05:11.276 align:middle
El punto clave más importante aquí es: las
respuestas JSON no son nada especiales.

00:05:12.176 --> 00:05:15.256 align:middle
La clase JsonResponse nos hace la vida más sencilla..

00:05:15.756 --> 00:05:18.186 align:middle
pero podemos ser aún más flojos!

00:05:18.186 --> 00:05:25.756 align:middle
En vez de new JsonResponse simplemente
escribe return $this-&gt;json().

00:05:25.756 --> 00:05:32.296 align:middle
Esto no cambia nada: es solo un atajo para
crear el mismo objeto JsonResponse.

00:05:32.916 --> 00:05:33.886 align:middle
Pan comido.

00:05:33.886 --> 00:05:41.486 align:middle
Por cierto, uno de los "componentes" de Symfony
se llama "Serializer", y es muy bueno

00:05:41.486 --> 00:05:44.936 align:middle
convirtiendo objetos a JSON o XML.

00:05:45.636 --> 00:05:48.456 align:middle
Aún no lo hemos instalado, pero si lo hiciéramos,

00:05:48.946 --> 00:05:54.406 align:middle
el $this-&gt;json() empezaría a utilizarlo para
serializar cualquier cosa que le pasemos.

00:05:55.186 --> 00:05:58.586 align:middle
No haría ninguna diferencia en nuestro caso
donde pasamos un array,

00:05:59.196 --> 00:06:03.436 align:middle
pero significa que podrías empezar a pasar
objetos a $this-&gt;json().

00:06:03.436 --> 00:06:09.726 align:middle
Si quieres saber más - o quieres construir
una muy sofisticada API - ve nuestro tutorial

00:06:09.726 --> 00:06:15.606 align:middle
sobre API Platform: un increíble bundle de
Symfony para construir APIs.

00:06:15.676 --> 00:06:20.776 align:middle
A continuación, escribamos algo de JavaScript
que hará un llamado AJAX a nuestra nueva ruta.

00:06:21.136 --> 00:06:27.546 align:middle
También vamos a aprender como agregar JavaScript
global y JavaScript específico a una página
