List

Build A Blog in 15 (more like 30) Minutes: Webpacker Edition

Build A Blog in 15 (more like 30) Minutes: Webpacker Edition

by Sasha Grodzins

In the video "Build A Blog in 15 (more like 30) Minutes: Webpacker Edition" by Sasha Grodzins, presented at RailsConf 2018, the speaker guides the audience through a live coding session where he builds a blog application using a Rails backend combined with a React frontend and a GraphQL API. This session serves as a modern homage to David Heinemeier Hansson's original talk on Ruby on Rails, where a blog was built in a mere 15 minutes. However, Grodzins notes that his version is unlikely to be completed that quickly due to added complexities.

Key Points Discussed:

  • Introduction to Technologies:

    • Grodzins introduces the main technologies used, which include Rails for the backend, GraphQL for API communication, and React for the frontend views.
    • He explains that GraphQL was created by Facebook to solve issues commonly found in traditional REST APIs, notably by providing a single endpoint and allowing clients to specify exactly which data they need.
  • Project Setup:

    • The initial setup of the Rails application with Webpacker is discussed, highlighting the significant reduction in configuration time thanks to Rails 5 and Webpacker.
    • The speaker executes the rails new command with the Webpacker extension and explains the necessary bundling and setup steps performed at the beginning.
  • Creating the Blog Structure:

    • The creation of the blog container and the integration of React components are demonstrated.
    • Grodzins explains how to structure components and utilize JSX for rendering views, emphasizing the component lifecycle methods, particularly componentDidMount() for data fetching.
  • GraphQL Implementation:

    • Grodzins walks through setting up GraphQL types and mutations, including creating a query to fetch blog posts and a mutation for deleting posts.
    • The use of a self-documenting nature of GraphQL is highlighted, where developers can interactively explore GraphQL queries.
  • State Management and Data Display:

    • State management in React is addressed, where the fetched data from GraphQL is set to state and rendered in the component.
    • The speaker demonstrates listing post titles and contents by querying the GraphQL API.
  • CRUD Functionality:

    • The implementation of create, read, update, and delete functionalities is completed within the live coding session, showcasing how to modify the application without needing a page refresh.
    • A brief mention of adding form components for creating new blog posts and inline editing features of existing posts is provided.

Conclusion:
Grodzins successfully builds a fully functioning blog application, demonstrating the ease of integrating Rails with React and GraphQL. The session illustrates the modern web development stack's capabilities while educating attendees on best practices for structuring React applications within a Rails framework.

Build A Blog in 15 (more like 30) Minutes: Webpacker Edition by Sasha Grodzins

An ode to DHH's classic, let's build a blog with a Rails backend using a graphQL API and a React frontend. Through this live-coding session, you will learn how to set up an isomorphic app, the basic concepts of each library, and at the end have a fully functioning blog application! Follow along on your computer or clone the repo.

RailsConf 2018

00:00:12.230 okay cool that sounds like I'm miked for sure hi guys are we getting started a
00:00:17.910 little late technical difficulties at a tech conference makes sense so hi I'm
00:00:22.980 Sasha Sasha grotton's I'm a Chicago native a dev bootcamp graduate yeah yeah
00:00:29.849 and I've been working as a developer at a consultancy called dev mind software also in Chicago and San Francisco if you
00:00:37.890 want to find me online I am Sasi Brody pretty much everywhere okay a welcome
00:00:44.010 thanks for coming to build a blog in a 15 more like 30 minutes this is the web
00:00:50.610 Packer edition and I also just added craft UL to the title because that's what we're using which is ban a common
00:00:56.820 theme throughout the past few days another common theme I found is like a
00:01:03.030 theme of nostalgia about Rails I would like the history of Rails track and all
00:01:08.040 that so this is also fits in there it's an ode to DHH of presentation of the
00:01:14.010 same name where he presented Ruby on Rails to the world back in 2005 I
00:01:25.130 presentation where he built a blog with posts comments pagination and like add some tests at the end then he does it in
00:01:31.439 15 minutes so that's been like blowing people's minds for over a decade and like has been a tutorial and reference
00:01:37.829 since so what is this talk this talk we're also going to build a blog it's
00:01:45.299 not going to be as revolutionary or fast hence the title and we're gonna be using
00:01:51.689 a react front-end graphical back-end and I'm going to show how you like get that all hooked up in a single rails
00:01:57.719 application that link is not active yet so sorry about that just ignore it it
00:02:04.740 will be on github as soon as I'm up at the station okay so welcome web hack for
00:02:12.270 the past few years my company has been building with these tools and I remember
00:02:17.910 like the first time we set up and up we had a front-end app and a back-end app one was reacting one was our rails
00:02:24.780 API and it took a full workday if not longer to get it all hooked up and talking to each out there and displaying
00:02:30.390 data on a page just because like the configuration like added so much overhead but then rails 5 was released
00:02:38.340 and web hacker made its debut and changed everything it like you could
00:02:44.160 initialize a rails app with pretty much no configuration and have react I'm
00:02:50.819 sorry we could have like any JavaScript library just configured to run your application so that was great
00:02:59.640 I have to be honest I'm working without my speaker notes that's why I'm like kind of struggling right at the first
00:03:04.709 moment but anyway that web hacker came out and it was awesome I think that's
00:03:10.379 all I had to say about that so what are we doing I want to just go over what our what our tools are right now so we're
00:03:16.980 going to use react to build all of our views the definition of react from the docs is a JavaScript library to build
00:03:24.090 user interfaces yeah it's a view library it is client to as a front-end although
00:03:31.769 since what is graph QL graph QL again from the
00:03:37.380 Dax a query language for your API what does that mean I think thing to think about here is
00:03:44.010 that react in graph QL are created by Facebook and they you know as they're
00:03:49.050 becoming one of the biggest companies in the world face some problems with traditional rest api is and you know
00:03:54.930 jQuery madness kinds of things so they created these libraries the like most
00:04:01.440 notable thing about graph QL is that it uses a single endpoint this is not a single endpoint
00:04:07.290 this is restful api and it's a screenshot straight from the rail stock so it should look familiar
00:04:14.180 so yeah the way wrestle api's work is you have different endpoints for like each action you want to perform in each
00:04:20.250 view you want to show so if i wanted to get a single article i just have to make
00:04:25.860 a request makes UTV request to get articles / ID past the ID another
00:04:31.820 parameter somewhere and what i expect back from that from a rails application
00:04:37.169 is like a full active record object which would be the ID any like fields i
00:04:43.979 migrated onto it and created that updated timestamps so like that's a lot of data and i might not always need that
00:04:49.890 so graph QL solves this in having a single endpoint
00:04:55.620 so here we see post slash graph UL that is the only way to get data in and out
00:05:02.729 of your your back-end so the way that works is you make your HTTP request to
00:05:09.479 the single endpoint graph QL and you pass in a graph QL query that looks
00:05:15.990 exactly like this shaped like JSON any kind of structure so if I wanted to get
00:05:22.260 the same data I just mentioned before from my graph API I'd say I need a post
00:05:27.300 with an ID and then the specific fields of data that I want to display on the
00:05:33.169 page so in this case I'd only get a title back I wouldn't get ID or
00:05:38.490 timestamps or anything else from that object so that's really nice because it is
00:05:46.080 small contained pieces of data and it makes everything very predictable
00:05:51.950 how does it work this is a big talk so maybe you've been to a graphical talk in
00:05:58.920 the past few days and if you have that's awesome but just a little overview there's the idea of types of mutations
00:06:05.280 in graph QL so a graph you'll type corresponds to some piece of information
00:06:11.520 in the backend that you want to expose to the front end so in our case today it's going to correspond to an active record model the mutations specify which
00:06:21.180 parts of the data and the back end you want to change so because you only have a post request that you can make you
00:06:28.530 have to say whether or not you want to get data or you want to change data via a title or mutation okay so the other
00:06:37.470 reason this isn't going to be as like fast and cool as the HHS talk is because I've already done some set up I did the
00:06:45.180 rails new command with the web pack extension where we're gonna use react as our front end that took like close to
00:06:52.320 three minutes to run in this Wi-Fi so I'm glad I did that also added the graph
00:06:59.340 to old library in the gem file and i bundled hopefully everyone seen a bundle
00:07:04.530 it's not very exciting I did run the rails Geographic you all install command
00:07:10.770 which is actually a really cool command I'm sorry you don't get yet today but that's the thing that basically sets up
00:07:15.840 the whole API it adds a line to our routes for this PostgreSQL endpoint and it sets up the controller with a single
00:07:23.190 method for that endpoint to hit and it sets up some route type of mutations for
00:07:28.860 us pretty nice we'll see all that in a second I added a model already the post model
00:07:34.920 and I seeded some data because you also don't need to watch me do that and it's
00:07:41.160 not so loud I added a single view page so that when we hit localhost / root we
00:07:49.110 don't get the like rails Friends image you don't know how cute it is we don't need it
00:07:54.750 all right that's it that's it for these slides get out of here all right the
00:08:00.660 first thing I want to do is I want to start the server so because we have our web pack server and our rails server we
00:08:07.170 have to start both so we'll say rails server how's that fontsize everybody good
00:08:15.620 nice nice Thanks okay and then on this side we're gonna use the built-in
00:08:21.810 command which is dot slash bin slash web pack dev server you can add a shortcut
00:08:27.540 in your package JSON to get like a faster shorter thing but I'm gonna keep
00:08:32.729 everything as default as I can okay so it looks like those Oh
00:08:38.940 oh my god that's like a lot of tabs how they're cool so localhost
00:08:50.640 is up and running it says hello from the index I added that to my single rails
00:08:58.830 view page so if I go in my views I've got this index of my index so this is a
00:09:04.440 rails a normal rails view it's ER b with a little bit of a little bit of text in
00:09:10.860 it but like i said i want all of our views to be built using react so i'm
00:09:16.470 gonna go try to find my react files is this this is probably impossible to see
00:09:21.990 it's so sorry but on the side we've got our normal app structure in this file system tree but the web Packer command
00:09:30.540 that the installation process added a JavaScript folder and it has to as a
00:09:36.720 single folder called packs and two files in it the one we're gonna be using today is called hello react so this was just
00:09:43.380 generated for me I haven't touched this since I ran rails new and this is you
00:09:48.930 know a react root note is what we like to call thee is where like you are
00:09:55.290 finding a document appending stuff and that's where all of your react content
00:10:01.410 is going to live so they've got this demo here and it says at the top like
00:10:07.830 you know grab this tag and put it in any
00:10:12.990 of your layout so I'm gonna put it in this application thing that I'm calling my layout so JavaScript pack tag hello
00:10:19.709 yeah so if i refresh the page I get a new piece of information there it says hello
00:10:27.270 react and that's coming from the component that was generated for me so
00:10:33.510 here's this hello and it's like calling props name and name is sent down here so - hello railsconf
00:10:39.590 save it go back I didn't hit refresh as hot reloading for me which is also really great
00:10:45.210 hello rails come so basically what I'm just proving here is that react is
00:10:51.210 loading and I didn't do anything really which is awesome the next thing I want
00:10:58.770 to do so we're building a blog right I need to build a blog container so I'm going to make this file called blog
00:11:03.840 container just dot J s the other thing
00:11:09.930 I'm going to do a lot of just feet up time as you snip it so like bear with me you don't need to see me type out all these words and fat finger L everywhere
00:11:17.510 there will probably be some typos so watch out all right so I'm going to
00:11:24.000 define a es6 class called the fog container that extends react component
00:11:30.350 I'm importing the component from the react library itself so this is a react
00:11:36.480 component they look like they had this render function because the whole point of a react component is to render stuff
00:11:43.610 so this is just a JavaScript function and it has this explicit return because we're in JavaScript and this what it's
00:11:51.660 returning is called JSX and JSX is the templating language used in react it looks a lot like HTML so it's like
00:11:59.040 really easy to write in
00:12:04.920 but it has like full JavaScript capabilities and a lot of built-in properties that are very helpful to us
00:12:12.880 so I have defined this blog container but I'm not rendering it anywhere so I want to render it into my like root node
00:12:21.040 my blog container I'm going to import from blog container and this stuff like
00:12:27.639 I mean I'm just going to delete it and now we don't need it instead of rendering the generated little tiny
00:12:34.779 component I'm going to render my blog container so at this point we should see
00:12:39.850 you know whatever is in the blog container on the page yeah okay great
00:12:45.850 it's very good it looks still so bad because of this thing I'll get rid of
00:12:51.130 this and now we have a full I mean our only of you as a react view so we're
00:12:57.699 going to just continue to build only in the blog container so what's a blog
00:13:05.320 without post it's nothing so we need to find a way to get some data onto this
00:13:10.390 page and the way we're going to do that is by making a request to our graphical back-end from our client here
00:13:18.990 so we need to go back to our graph QL and set some things up so as I mentioned
00:13:24.990 the graph QL instillation added this gradual folder and then two folders
00:13:31.350 within four mutations and types that's where we're gonna keep our data alright you know our definitions of these
00:13:36.870 graphical types so if I look here there's a query type to mutation types
00:13:45.050 with a bunch of like test fields you know we could play with those but I'm gonna skip over them for now what I need
00:13:51.420 is I need something I need a new type these things are working off of default type strings so this test field is
00:13:58.920 returning some kind of default graph QL type a string as you can see here that
00:14:05.370 string is hello world so I need to define a new type mentioned everything
00:14:11.220 has built off the types of mutations so there is luckily a command for this as well no actual object so this will be a
00:14:23.850 post capital P post with a title these things are going to correspond to what's in my database because that's what I
00:14:29.880 want to be available to me on the front end quite cool so it made it a single
00:14:37.080 file called post type you know I don't look for that here it is so there it
00:14:42.270 just generated this big thing for me which is awesome and I know that I have a post type now a graph QL type called
00:14:48.870 post type and it has these fields on it so what do I need to do with them I need
00:14:54.600 to expose them to like the root layer of my API so the way you do that is you
00:15:00.060 define a field here and whatever II want to call that I'm gonna call it posts I want to list a post so I'm gonna say
00:15:06.210 this new type ID is that it it's post type and then part of the DSL like the
00:15:12.180 the graph QL library comes with this two list type method so that'll basically
00:15:18.600 just return a an array of post types however many I'm gonna get in my resolve block Oh
00:15:26.949 let's suppose so the like other really cool thing about graph QL is that it's
00:15:32.829 pretty much self documenting based on just what I write here like you know what you're gonna get because I just said okay I'm gonna return a list of
00:15:39.670 posts so this is a resolve block it's a lambda and it has these three things
00:15:46.269 that are coming back from the graph you'll controller itself but it don't really matter because all I want from
00:15:51.279 here is an active record column that is post all I want all the posts I don't
00:15:56.769 care what order they're in I don't care anything about them that's what I want so there's another really cool thing
00:16:04.059 about graph QL I don't know if I mentioned this yet I can't remember but it did also initialize with this other
00:16:10.839 route called graph EQL or graphical whoever you are however you want to say it's time and this is an in editor IDE
00:16:19.569 for you to test out your queries are you right so like the query query we just
00:16:24.939 wrote is that okay okay that's the best
00:16:34.629 kind of feedback okay cool so well I'm like I hadn't written that yet so this
00:16:40.869 is a documentation Explorer it's a great name for it that's exactly what it is you see it has their route types here of
00:16:47.709 query and mutation so I can click into this and say like what do I have available to me in my graph QL API that
00:16:55.600 is posts to field so there's posts in our test field and we can see over here
00:17:00.999 on this root query type that we have these two fields posts and testicles so
00:17:07.139 okay not this this is a graph QL querying over here this is exactly what
00:17:13.419 we're going to ask the database for so I start typing it's very very helpful and
00:17:20.319 that it tells me what I can type basically like I could type in a and it will say I go there's nothing with that
00:17:25.839 what uh what do you want really and I think I want titles so I'm getting some
00:17:33.820 data right there are a couple of blog posts that I seated as I mentioned two of them are just things that I wrote
00:17:43.100 one of them is a real blog post from the deffend blog so that's great like this
00:17:49.250 is a JSON looking object I feel like I know how to work with that and I'm only getting titles which is exactly what I
00:17:55.880 asked for if I wanted content as well I'd have to put content in there explicitly so that
00:18:02.450 the API knows what to get you know we could get all three of the things like
00:18:07.730 me but I really just see titles I go
00:18:13.330 yeah so what do we do with this type what I do is query I'm actually trying
00:18:20.630 to remember so we're going to go to our JavaScript again we're going to flip back to our react and this is our blog
00:18:27.170 container it doesn't do anything and really what we need it to do right now is go make a request to our API so I'm
00:18:36.110 going to define a function called get all posts well okay so these functions
00:18:46.400 are available to like within the component there just scubs functions to this pod container component so get all
00:18:53.660 posts I didn't want to add any more libraries this is just the basic config
00:18:59.150 so we're gonna use the fetch API here's a nice big snippet for you um so the
00:19:05.630 fetch API is just you know built in to react right now I'm just great so you can make any kind of HTTP request with
00:19:12.170 the fetch you just specify the URL here the method we know it's going to post
00:19:18.310 headers and then in the body this is where you're going to set your Jake your
00:19:23.780 graph you all query so you just kind of you give it a key give it a string and
00:19:30.830 then I'm going to literally copy this graph query I was playing with and back
00:19:36.560 EQL and paste it that's what I'm going to do
00:19:41.650 and I'm going to you know resolve the promises veterans of promise yet to
00:19:47.200 resolve it once to JSON and the New Year's all but again and we'll see what we get in this last part here
00:20:03.140 debugger because I'm not actually calling this function anyway so where do I want to call the function
00:20:08.510 I want this data and the fetch request to have been called before the page
00:20:14.120 renders so components have these things called lifecycle methods and we're gonna
00:20:19.610 use component did mount there are a couple of them and they're totally worth reading about and they're very helpful
00:20:26.950 component amount and I'm gonna have a component to mount called get all posts so this will call before so fast it'll
00:20:37.130 call before the render loads as you kind of just saw there like it's just like
00:20:43.179 pops open here so I'm invited bugger this is too big to even operate in what
00:20:51.020 do I have so I have this response data and it's got posts yes okay so I've got
00:20:57.020 an array of posts coming through at the end of that fetch which is awesome because that's exactly the data that I
00:21:02.150 want to show in my you know in my
00:21:07.620 so what I do with this data I'm here I've got response data posts that's an
00:21:15.210 array so I need to have that accessible to the render method the way I'm gonna
00:21:22.140 do that is use another built-in react
00:21:27.539 function called state so or a react property and Arledge sure we want to call this that state is built into every
00:21:33.600 react component as well so you can pretty much hold anything you want state I'm gonna hold posts here and just set
00:21:39.750 it as an empty array so this is like my initialization of the state of the react components like there's nothing there I
00:21:46.320 can't just call this I get all posts here except I see it works so the order
00:21:51.870 in which things are going to work is the components going to load from the root node it's going to call States state
00:21:58.679 will be set to this that State DOT post is an empty array component did mount is
00:22:05.460 going to call next and it's going to call this that get all posts that I'll call our fetch method and at the very
00:22:11.970 end we're going to reset the state reassign that empty array into actually
00:22:16.980 having data so it'll say pose
00:22:23.330 data posts so then state is available to
00:22:28.950 every part of the components so I can do a oh not the head posts equal since that state posts so this constant data base
00:22:38.700 and then I'm gonna just iterate over them in the JSX so to evaluate any
00:22:44.880 JavaScript you use two curly braces and JSX and we can just use and you know
00:22:49.890 normally es6 map for a single post and you give it an index
00:23:03.540 right so then right it looks like HTML it's not HTML JSX so you do curly braces to evaluate at the post title alright
00:23:12.120 cross your fingers guys what we have we have oh yes we've got a list of titles
00:23:18.000 oh yeah ok great so like that still
00:23:23.130 feels good I've been doing this for a really long time and it still feels very good and like such a relief okay what do
00:23:33.030 we want to do actually I want to show the post content as well so everything's
00:23:39.820 going to be on the single page I don't have a router so we're not gonna have like a show page it's just all going I'll be right there on this single page
00:23:46.450 so I'll do this okay great adjacent JSX
00:23:52.120 elements must be wrapped in and closing tag learning a little bit about JSX here that just means that you can't have two
00:23:57.910 siblings like right there next to each other they need to be wrapped in something I'm gonna wrap them in a div
00:24:05.230 you can wrap them in whatever you want and then that should load properly but
00:24:12.460 we don't have any content maybe you know why but the reason we don't is because I'm not asking for it yet the graphical
00:24:19.660 query is like you didn't ask for content I'm not going to give you any content so I need to put it in the query and I have
00:24:25.540 to come back now we have some content so that looks like garbage but there's
00:24:33.530 no styling there's not going to be in this talk so just hold site you know
00:24:39.440 please there's data ah cool okay so we are rendering blog post I think that's
00:24:45.770 really great so you know how to get database from our back-end now we need to learn how to change some data so I
00:24:54.200 know this is called a credible we're going to go out of order and we're going to do the D of crud first so we're going
00:24:59.900 to delete really like when it comes down to it the other thing about the graph QL
00:25:06.530 is that you only have a mutation and a query you don't have crud you don't have
00:25:12.370 gets and posts and put some patches and those deletes you only have one thing so it's not exactly cred anymore like the
00:25:19.549 definition of crud is a little different here but let's do this what am i doing
00:25:26.410 need a delete link so I know that the delete link itself is going to make
00:25:34.520 another fetch request so just to keep it click contained I'm going to make a new component for delete link call it delete
00:25:42.679 link and I'm just going to put the word delete they do you'll give it a class which is you know link then I'm going to
00:25:54.500 render it I'm going to render it in the bog container import link I'm going to
00:26:04.790 render it right below the post title
00:26:11.720 let's see oh yeah okay so now each each row of posts adds a delete it does not
00:26:18.769 look like a link I'm going to just very quickly change that because that's too
00:26:24.139 crazy that I'll say links are you really
00:26:29.809 blue so the other really cool thing about having a react app in your rails
00:26:36.860 app is that you get the asset pipeline which we all know and love and I like that a lot so cool this thing doesn't do
00:26:44.450 anything it's a div that styled to look like a link what I want to do is give it
00:26:50.299 an on click Handler so you call a function called like handle delete
00:27:00.929 I'll define handle delete as a function again in this component and we're gonna
00:27:06.869 make another fetch press so the same thing the same structure but now we need
00:27:12.119 to make a different kind of query essentially here we need to make a query for mutation and we don't have any
00:27:19.590 mutation so we have to go back to graph no no I don't see graph you all
00:27:30.590 mutations yeah mutations are empty so I'm going to create a graph QL mutation
00:27:39.320 and it's going to be delete underscore post that's just the way it's going to
00:27:46.259 be so that added a couple of things here for us it added a file under mutations
00:27:51.990 delete posts so this is not the same kind of definition we've been seen the
00:27:58.259 post type itself was just a graphical object type whereas the delete post
00:28:03.629 mutation is built off of a different module but it looks kind of similar and
00:28:10.379 in a lot of ways so it's actually really nice and the other thing it did is it added oh you guys can't delete this yeah
00:28:17.399 I'm gonna remove you it added the field for me on the mutation root type so delete post you know has a field now on
00:28:25.110 this mutation type okay so let's see if this thing has directions for me it says
00:28:31.320 to do define your or turn fields so it's suggesting I return a post but because
00:28:38.250 I'm deleting here and actually just going to return a message and I'm gonna use the defaults Oh graph you'll type of
00:28:45.149 a string because I'm just gonna say at the end of this you know if all goes
00:28:50.399 plan message post was deleted that's what I want to see somewhere probably in
00:28:56.639 a flash message eventually but maybe just my console for now and then the
00:29:02.370 next thing that's going to do define arguments so inputs field name type string this also doesn't feel quite
00:29:09.149 right because when we delete we usually delete by finding links the ID and then deleting the object that we found so the
00:29:15.210 input field is going to be an ID and again we can use the generic craft all types of ID and to do resolves the
00:29:24.480 function so again let's just do some active record stuff let's find the ID
00:29:30.440 which I'm gonna pass through in the args kind of like how we saw in the query before and I will just destroy that pose no
00:29:39.840 questions I spell it wrong just right cool D story happens to me all the time okay
00:29:49.749 yeah so we're just gonna we're just going to assume that works I'm not gonna I'm gonna put today so let's see we can
00:29:57.100 use graph EQL test that out again if i refresh this page look at our new mutations we have a single field for
00:30:04.570 delete post it takes input so I think the same way that I created the query
00:30:11.019 over here I can do the same start typing delete post input and then put type is
00:30:17.739 9d right so I'm gonna delete the first one let's see okay
00:30:25.960 so I just had a guess there I assumed there was a post with the ID of one but
00:30:32.320 it does say that the post was deleted so if we go back to our front end and we refresh there are only two which is
00:30:41.759 exactly what I wanted cool so I'm gonna do the same thing
00:30:46.960 where I copy this mutation put it into
00:30:57.960 oh and I don't want to hard-code this so
00:31:05.340 like somehow I need to get the post ID and the way I'm going to do that is if I
00:31:10.890 go back to the blog container we're iterating through these posts right so this is like a post row and the div
00:31:17.250 itself is contained to a specific post so I can send in a property called post
00:31:23.159 ID which would be post dot ID this isn't
00:31:31.230 going to work immediately because I'm not requesting the ID so if I want to do that I have to
00:31:36.299 put it here now I'm calling all three of the fields that are available to me I'll
00:31:42.809 have that in my response and I can send it through to the delete link so the
00:31:47.880 delete link can access these kind of properties via a call that looks like
00:31:53.490 this this dot props dot host ID so
00:32:00.090 that's how you can pass data from your parent down to your child and that's a very common pattern and react like
00:32:08.130 precisely for this kind of demonstration let's see so we're gonna get our
00:32:13.200 response back hopefully it's good to hopefully we get a message here right so console ID the message we don't really
00:32:20.340 need to have state in this component this component is just a link so I'm not going to try to set the state here but I
00:32:26.279 do really want to reload the post at the
00:32:31.559 end of this because I don't want to hit refresh when my posts are deleted so I
00:32:37.799 can actually demonstrate see we're right here yes oh okay well that's just a warning
00:32:46.670 I'll fix it in a second if we hit delete Oh got undefined it
00:32:54.170 didn't work oh wow okay so now anyone post the delete is working I am
00:33:00.230 surprised mostly I'm just thrown off by that huge gross warnings I'm going to fix that
00:33:05.660 it's bad morning and saying that when you iterate over things you need to pass in a key with a unique value so many of
00:33:13.190 the index of the map that'll be pretty unique it's not what that warning is gone which is great if I hit delete
00:33:19.400 again hit refresh now I don't have anymore anymore posts to work with so I
00:33:27.980 have to receive a sec okay great I'm actually gonna see it again let's do it
00:33:33.170 let's get a bunch of them cool okay so we have like six and I count yeah okay
00:33:42.290 it's alright I'm hitting delete and then I have to hit refresh to get like a new list of posts back because the front end
00:33:48.980 it doesn't know what to do yet so they go back to my delete link
00:33:54.900 I've already written this function somewhere right the this dot get all posts but that is not available to this
00:34:02.340 component because that is defined in its parent so much like how he passed down the property for posts ID I'm gonna pass
00:34:09.150 down at this function as a property as well to get all posts this time get all
00:34:14.970 post so then I can go back to my delete link and again call it via props that
00:34:20.640 get all posts so not you can pass like pretty much anything done from a parent to a child via props there that's a
00:34:27.660 function we passed like it strings you can pass to ever you want let's see see
00:34:34.500 we're at I hose that and hit delete yes okay so that thing is deleted out of
00:34:42.360 the database and I'm gonna do a couple more because there are too many awesome
00:34:49.250 got still leading we have I'm like stunned because I still
00:34:55.840 have time and like every time I've gone through this I've run out of time before I got here so cheers to talking really
00:35:03.670 fast and for things going pretty well
00:35:09.960 let's see him I guess we should just keep going we may as well do create oh I
00:35:19.150 don't know that sounds like kind of ambitious let's try it let's see if I we get I'm going to yeah I check all this
00:35:29.650 out so everything on here is going to be in a branch eventually I'm sorry not a branch a git repo and everything is like
00:35:39.610 branched out pretty precisely so if you wanted to check out different spots of the tutorial that will be available you
00:35:46.600 could start from like wherever you wanted they build on each other so like in this tutorial it's gonna go see first
00:35:53.530 CF cred - or RF cred CF crowd G you have got to do cred I find that to be like
00:36:00.790 the most normal way to build your application but I started with you today because why not spice it up but if we
00:36:08.470 want to CC let's just like get check out see of crud
00:36:14.170 now let's just see what it looks like completed I know let's refresh that's
00:36:22.120 what they all let's go through all the branches okay so here I did add a form
00:36:27.630 this form lives in its own component
00:36:33.270 form so again it's just a little component it has some state for title
00:36:40.420 and content this is like exactly how the docs of react to tell you to make a form
00:36:45.670 so there's plenty of information about like why this is how it's set up but forms again look a lot like HTML but
00:36:54.490 they have all of these handlers and properties that help like set the states and make changes and submits data so
00:37:02.890 these inputs this unchanged or claims handled in change and handle input change it's just
00:37:07.970 resetting the state so for us when we are creating our mutation we're gonna
00:37:14.599 send along the title and content from the state that is the title and content that is here so like Oh
00:37:26.050 right okay so nothing's happening because we don't have it create mutation so let's see oh yeah we do I forgot okay
00:37:33.740 so I have already created my create mutation let's just go look at it create
00:37:39.080 post so I did this the same way I made my delete post which was rails Jeep fql mutation create posts this one you can
00:37:48.350 see like has a return field for the post type unlike delete which was returned filled
00:37:55.370 up a message I think is what I did this one has input field for title and content and here the resolve block again
00:38:02.810 actor record whatever you want to do from you mutation is or we're gonna create a post so we create a post with
00:38:09.470 the title and content that comes through in the arguments iam and actually that's
00:38:14.930 like oops there's a bolt to us here this fetch has
00:38:20.420 a mutation called create post title content they all start to look a lot
00:38:25.460 alike if you can't tell already let's see let's check out
00:38:33.540 it's an excitation still this might be
00:38:45.820 the end of it this might just be like everything working so we have this delete can delete things and I can edit
00:38:52.960 so the way I chose to edit for the sake of this demo was to do it on the same
00:38:58.630 page right like I said I don't have a router I don't want to like have a page just to view and edit form so you can
00:39:05.230 edit and Oh tips for petting every dog on the street or something
00:39:12.160 like that I wrote that you can edit this just be like wooh that says phew but you
00:39:21.040 know I do mean wooh and then it edits in place so that is
00:39:27.280 more or less the completed crud application that I meant to demonstrate today and that's it actually so thank