Build an Event App with Vue.js, Gridsome & Strapi.js

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

I had an issue following this tutorial. Certain steps were skipped.

👍︎︎ 1 👤︎︎ u/alteDesigner 📅︎︎ Mar 22 2021 🗫︎ replies
Captions
[Music] hi everyone my name is gwen i am a software developer and i also run the youtube channel and twitch channel called faraday academy and i am very excited to be able to come on traversing media's channel today for this project now specifically i will be building an app with gridson which is a static site generator for vue.js and backend with strappy feel free to leave any comments questions or feedback in the comments below i hope you enjoy this project this app is a virtual events platform inspired by current web apps like eventbrite it also filters in between tabs for different categories of events all of the information for these events is stored inside of the strappy api that we are going to build and we pull that information into grid sum and display it and we can search by the title as well by clicking on any one of these cards we can see an individual event page for that event that is made with gridsome templates and then we can go back to the home page to build this api i'm going to be using a cms called strappy now like it says strappy is 100 written in javascript and it's open source so you can customize it as much as you want to however since this tutorial focuses on grid sum and we won't really be diving too deep into strappy we aren't going to be actually touching the code we are just going to be setting up a strappy server locally and using it as an api with a database in order to store and manage our events on the back end and then we're going to hook gridsum up to it on the front end if you want a more in-depth tutorial on strappy then there is already a really good one on this channel traversing media so you can check that out after if you want now the reason why i chose strappy specifically is that unlike a lot of cmss with strappy it's really easy to create custom types for example instead of blog posts i could create events and then update those events inside of the cms admin interface and then i can pull all those events to my front end with a simple api request and you'll see what i mean with setting up custom types once we start setting up strappy so i'm going to go ahead to get started and then scroll down here to install strappy instead of yarn i'm going to use npx so i don't have to globally install anything here i'll just copy this command and now i'm in an empty folder on my computer where i want to put both my strappy api and my grid some front end later so i'm going to paste that create strappy app command it's called my project i'm going to call it by the app name so i'll call it events api and now it set up my strappy application and it also ran it at the same time so it's available at localhost port 1337 admin and if i come to the admin page there's a form for me to set up my root admin user i'm going to call it gwen f just give it any old password and for the email i don't need a real email so i'm gonna do gwen example.com of course i don't want updates and click ready to start you've already seen a small demo of the app the two types of content that we need to retrieve from the api are events and then we need to categorize those events so we need a category related to the events so i'm going to create an events content type and call it event click continue and now i can add fields to the event so i'm just going to add these real quick the first one is a text field called title it always gives you some more options down here this will be short text which is good because i want to be able to search on this field later and i'm going to click add another field now i'll choose text again and this time it will be called description for the description of the event long text click add another event so i could have actually done the description as rich text but i don't want to get too fancy with it so i'm just leaving it as is and now i need the date and time of the event so i'm just going to call this date and i'll choose date time here add another field i need a number field for the duration of the event the number format here is going to be an integer or actually i'll choose decimal because the event might be something like one and a half hours so i'll pick this one add another field i'm going to skip category for now because i'm going to make categories later and then the last field will be another integer field or rather a decimal field which will be price of course there's no location for these events because they're all virtual so those are all the fields i want now click save and i'm going to save the event type now i have created an event type you can think of this kind of like a schema for a table in the database now by default strappy uses sql lite which is fine for what i'm doing but it's pretty flexible in letting you use or postgres or really whatever kind of database you want to use also notice that i gave this a singular name here but when i look at the table it's actually plural here events which is pretty similar to what you'd see in other cms admin interfaces like django so i'm going to click on events and you can see there's an empty table now i could add a new event but actually first i forgot to come and add a new collection type for categories so i'm going to create it here with the category display name click continue and the first field i want here is just text this will be the name field which will be short text just the name of the category like music or art and i'm going to add one more field and now this field is going to be a relation type click on that and now category is going to have a many-to-many relation with the other type that i've created which is event so events and categories are now related an event can have many categories and a category can have many events associated with it so i will finish that and now you can see i have this category schema and then i have a categories collection over here first i'm going to add some categories here so i'm going to add a category and just call this music i don't have any events to associate with it yet so i'm just going to save it and then i'll add another category and i'm going to call this coding so people can host coding events save that all right so now i have two categories here and i'll go to events and i can add a new event here and i'm going to call this code and coffee description we get together and chat about code okay i'll pick a date which is just going to be tomorrow the time is fine duration i'll say two hours and the price is free so zero all right and now i can come down here and relate category to it so the category will be coding and everything looks good i'll save it so now i have this one event and i also have some categories so i want to make an api call and retrieve my events or one event in this case so i can actually do this by typing in localhost port 1337 slash events and now i have hit the events api but it's telling me that it is forbidden and that's because i have to grant access to that api so really quickly i'm going to come down here to roles and permissions and i'm going to come to public and since this is a tutorial api i am actually going to set all of these to public so i can do any of these operations from any application and i'm also going to be able to make get requests on category and i'll basically be able to do any kind of crud operation on events and i'll save that and now if i come back to my browser and refresh this page i can see that i was able to retrieve my event and now slash events would be a list of all of the events in the database and then i could do slash events slash one and this would be only that one event and you can see it changed from an array of objects to just one object so i'll be able to access this api from the front end and now off camera i'm going to add more events to the database and update them a little but that's basically how it's going to work and now we'll move on to actually creating the front end in grid sum so what is gridsim it's basically a vue.js framework for building statically generated websites and apps that are fast by default now what does it mean fast by default so gridson provides you with a number of optimizations to make the user experience really fluid like pre-fetching for example when a user navigates to a page with a link on it then gridsome will go ahead and pre-fetch static content for the next page just in case that user clicks on the link that will be a seamless transition when the user is navigating page to page it is also set up as a progressive web application by default so this works even if the user is offline they also provide you with a special image tag which basically loads a really low quality of all images on the page at first and then it will fetch the high quality image for any images that are currently in the user's view so if you had a blog with a whole bunch of posts that each have their own image as the user is scrolling through your blog listing page the high quality versions of all of those images will load as the user scrolls this is a nice user experience because the content isn't jumping all over the page as images are loading and the initial load can also be much faster another benefit of grid sum is that it's seo friendly many single page applications and single page application frameworks struggle with seo because it's more difficult for things like search engine bots to crawl the page and index it for a search engine well gritsome takes care of that because it renders all of the static content up front so bots can crawl just fine and then it loads the vue.js javascript so it can still work like a regular spa one other thing that gridson provides is a simplified way of building view applications some abstracts away some of the boilerplate that you would normally be coding with a regular view application for example it handles routing automatically based off of your file names there is also no need for view x because it has a graphql data layer that simplifies and pools api calls all in one place now the data doesn't have to be just api calls it can also be local files markdown and it integrates with lots of jam stack services so there are a few frequently asked questions about gritsum that i just want to cover real quick and i first want to mention that as a former gatsby user now that i use gridsome they both feel almost identical to me in fact the gridson team says that the project is heavily inspired by gatsby which if you don't know is a react static site generator that works like gridsome using graphql and the same kind of optimizations and jam stack integrations so the difference is basically gritsum is for vue.js and gatsby is for react now some people ask why they don't see any big companies using grid some and i think there are a couple reasons for that for one it's a relatively new project it hasn't even hit version one yet although there has been quite a bit of active development on it and they have a roadmap where they're working towards that version one goal also gritsum is optimized for small or maybe medium-sized projects i can't really see it being used on a very large project some of the best examples for use cases of gridsum are blog pages and portfolio pages store websites local websites informational websites i don't think it would work very well as a robust application like reddit or something like that another common question that people have is what is the difference between nuxed and grid some so next is a vue.js framework where you can build all different types of applications but it's mainly used for server side rendering although you can use it to build single page applications or as a static site generator like gridson now at first glance they look extremely similar even their abstraction of route handling is virtually identical the two projects what they cater to and especially the development experience so grid some was built with jam stack applications in mind and the graphql data layer and how it's set up is unique to gridsome with nuxt you can absolutely use graphql or rest or whatever you want but you are either going to be doing it from the component just like you would in a regular vue.js application or from view x which is automatically set up for you in next now grid sum doesn't use view x because of that graphql data layer so those are some of the differences if you want a short and sweet version next is better for larger and more robust applications and gridsome would be better if you're building a jam stack project or if you want to spin up a simple static site quickly now let's talk about installing and setting up gridsum the first thing it prompts you to do is to install the grid some cli tool and instead of installing it globally you can definitely use npx it doesn't matter but i'm going to copy this command and i'm going to make sure that grid sum is installed now that i have the grid sum cli installed i can use the grid sum command from my terminal and create a new grid some application and i'm going to call this the name of my app is events and then i'll call it front for front end okay and now if i check out what's in this directory i have the events api which is the strappy app and events front which is the gridsum application so i'm going to move into the grid some application folder and before i run the grid some development server i'm going to open the code up in vs code and let's take a look at the files we receive out of the box so it comes with a package.json file and these three scripts so you can build for production to generate all of your static files so you can upload them to the server develop is the command that you run to run the gridsum development server as you are building the application locally and the explore command is what you use to start a graphql playground you can see here there is only one dependency gridsum and we'll be adding more as we install gridsome plugins and a few other things like a ui component design library now there are two grid some specific files here first the grid some config will just contain any plugins that we add and the configuration for those plugins the grid some server js file is an abstraction that lets us interact with the gridsim server we get access to the api here with lots of different methods that we can use for that and this is also the file where we will be pulling in all of our external data such as from our strappy api the static folder is just like any other vjs static folder it's for files that don't need to be processed by any build tools they are just copied directly into the dist folder with the rest of the statically generated content so the example they give here is a robots.txt file and now for the actual grid sum application code so if you start a regular vue.js application you always notice a main.js file and an app.js file well by default grid sum abstracts the app.js file away from you and you can add it here only if you want something custom the main.js file is a little bit different as well instead of exporting a vjs application it exports a function where you pass in view and you can set different options and things from inside of this function such as registering global components like this layout component and then just briefly what all these folders are for pages are for each view of your application for example the main index page about page contact page etc you'll have a page for each of those inside of pages components are for anything that you want to import and display on a page and this is no different than any other vue.js application you can create as many components as you want to break apart or reuse code and then import them into your pages layouts here and we will see this in the browser in a second it's basically a way to define layouts for different pages if you have groups of pages where you want the same nav bar at the top the same sidebar some of the same features then you can define a layout component and it always comes with this default layout which you saw was registered in the main.js file and then pages are basically displayed inside of this layout component in the slot tag templates are a little bit more advanced they're basically four graphql collections and the naming of the templates are important they have to match the graphql collection we'll talk about those a little bit later because it's hard to explain what they are without showing an example let's run the app from the terminal and see what it looks like so i can use grid some develop for that to run the development server or as you saw we have an npm script so i can use npm run develop and that basically runs the grid some develop command and it's ready to view on port 8080 this is the default site that gridson provides with the home page and the about page and i'm actually going to bring the address bar into the view so you can see that it's actually routing so you can see just the home page and also the about page at slash about now if you look in the code here you'll notice there is no view router there's no router file where you're defining routes for pages and that's because grid some takes every single page or folder in the pages directory and creates a route for each one of course index is a special name so that's just the home route and then about or any other name uses slash name so that's why we have the slash about route one more thing to cover before we jump into building this application and that is graphql grid some has a graphql data layer where all of your data sources that are defined in that grid some server file are pooled into a graphql schema and then you're able to query that schema in your components now you don't really have to know graphql before watching this tutorial as we're going to go over some of it as we go along and you'll see how to explore graphql and also make your own queries if you haven't worked with graphql before the basic premise of graphql is that you can query only for the data you want and it gives you a single endpoint to query all data so it's not like a restful api where you have slash users slash event slash tags and so many other endpoints and you have to query all of the different ones in graphql you just have one endpoint to query now normally in an application you would need to define a graphql schema for the structure of the data but with gridsum it really handles all of that for us and even though we haven't set up any data at all with graphql there is already a schema set up for us that is available to query out of the box as you can see it doing in this component so normally in a view application you have this template tag you have a script tag and then you have the style tag well you still have all of those three tags to use in gridsome just like you were programming a normal vgs application but you have more tags in grid sum which are your query tags so you have like static query and page query where you can query this graphql data but what does it mean to query for metadata site name so actually gridsum sets up a tool for us to be able to try out and inspect queries so i'm actually going to copy this query here so i'm going to go to the browser and go to localhost 8080 forward slash and then three underscores so triple underscore explore and this is the graphql explorer that it provides a graphql explorer is not actually unique to gridson you'll pretty much always have an explorer like this but it is a nice feature that it sets it up for you out of the box and gives you an endpoint to access it and if you forget what that endpoint is you can always look at your development server because it shows you the graphql explorer right here first thing i'm going to do is to paste in my query on the left over here let me zoom in on this and this is the same query that that component was making querying for a site name inside of the metadata object i'll hit run and you can see that the site name that i requested was returned to me now where did this site name come from it came from this grid some config file so if i change the name here to e events i can now query again and actually had to restart my server for the change to show up i can see that my site name has changed now what else can i query for actually by clicking on this schema button over on the right the schema window pops up where i can explore the schema and i can see that i was querying for metadata which is this type so type metadata and these are all the attributes on metadata that i can query for so for example i could query for site description and also site url and you can see that when i'm typing it automatically tries to complete the words as i'm typing them we close schema and let me run this and you can see that i got empty strings for site description and for site url there well to fix that i could just add a site description here and i'll say post or find online events i'll restart my server and i'll rerun this query and now you can see that my site description has shown up if i look in the app you can see that now it shows events here and that is because my layout component is querying for site name and then it displays site name here now it is dollar sign static here and that comes from the static query tag and then dot metadata is the name of the query and then site name is the attribute name that we queried for now i could add site descriptions since i added a description in the good some config let me add that here cite description and then i'll go up here right below the header and i'm going to put a paragraph tag with the double curly braces and then i'll do dollar sign static dot metadata dot site description and now if i look in the browser you can see that right below the header it shows my site description and even if i navigate to about it's still there because the slot where the pages display is right below that paragraph tag that i added that is a basic overview of how querying works inside of grid sum so the last piece of setup here is to set up a design framework that i'm going to be used called beautify it's probably the most popular design framework and ui component framework for vue.js and i definitely use it a lot in my projects because there are just so many features so many components provided by this framework so to install this with grid some i'm just going to search through the docs and they have a section for using css and design libraries in gridsome so i'm going to scroll down here it shows you how to set up sas if you want sas and viewitify so viewfi has several steps to set it up with grid some and i'm going to go through these one at a time now if you set up viewify in a regular vue.js application then the viewify docs will recommend that you install it using a vue cli plugin but it won't work if you have grid sum so you'll have to manually install it with npm but it's still pretty easy to set up so i'm gonna copy this npm install and i'll stop my server npm install vuedify and now that it's installed it's telling me to register the vuedify plugin and i also need to set up the viewify css as well as the icons which i'm just going to use the standard material design icons for this and right now it's differentiating between beautify version 1.5 and how to set that up and beautify version 2.0 and i'm going to be using 2.0 here and i basically need to copy all of this and put it into my main.js file so i'll go in source go to main.js and if i paste this there will be some duplicate code you can see it gave me the initial default layout component that i'm registering globally and that's pretty much all my exported function was doing up here or that is all it was doing so i'm going to get rid of that and then default layout is being imported by the code that i copied so i'm going to get rid of that too and you can see now i'm importing beautify now i'm importing the css as well so i get the styles and then i'm using this cdn for material design icons and i'm pulling those in and i'm gonna have to get rid of these three dots that's not correct syntax i'm not setting any options right now but i'll leave the options in case i want it later and now it says there is one more thing that i need to do in order to build my application with vidify and that is some webpack config and for that i need to install a plugin so i'm going to save this or copy this go to my terminal and i will install that plug-in okay so that installed and now it's saying that i should modify my gridsome.server.js file to include the webpack node externals package and whitelistveedify so let me copy this and i will go to my server.js file now i know i said before that the plugins will go in gridsim.config but these are actually gridsome plugins and not a package for webpack so i can put those in my server config here okay now i added my api.chain webpack to whitelistveedify so let me come and run my server again npm run develop and now back in my application i'm refreshing it and you can see it definitely did something to the application and now the new layout is actually because beautify changed some things and i have also not properly set up beautify in my components yet so let me go and do that really quickly i'll come into layouts and so my main layout i need to put a beautify wrapper around here in order to use viewfind properly the first thing i'm going to do is get rid of any styling that this application already has and i'll also replace this div tag now with the beautify wrapper tag that's required for my application which is v app so now everything on my page is wrapped in the app container this header is my nav bar which i will change in just a minute over to being a view to find navbar or rather called an app bar in beautify but this slot i want to wrap in a beautify content tag which is now called this was recently renamed to v-main let's see if that changed anything in our application and you can see now everything is stacked and that is because of beautify's flexbox or that it uses flexbox and we're going to update this app to look much nicer anyway and now back in my component i am going to delete the whole header and also delete that description that i added now that i've removed the top navigation from the app i'm going to go and find a beautify alternative in vidify the top nav bar is this component v app bar and i'm not going to talk too much about this but if you want to know more about beautify's app bar options then their docs are really nice where they give you these interactive playground examples so you can see all of the different features now one thing a lot of people have questions about on this component in particular that i just want to mention is that there is this v app bar and then there is also a v toolbar and when you look at it they look almost identical where you can put a title a draw menu icons all of this stuff so what's the difference basically a toolbar is something you could put anywhere in an application you could use it for markdown editor as a toolbar over a map or anywhere else and the app bar is specifically designed to be the main navigation for your website or app and so there are a few extra features in the app bar like scroll animation so you can hide on scroll inverted scroll all these other things that aren't available in the toolbar so we will be using the v app bar component for this so above the main content i'm going to add this v app bar component and i'm just going to close it for right now and i'll add a title inside as well now in viewdify you have nested components for a lot of the components so basically components that go inside of components so inside of the v at bar component i can have a v toolbar title to put basically the brand or the title in a nav bar now the reason why it's called toolbar title instead of app bar title is because like i mentioned before these are two very similar components we'll add bars built on top of toolbar so all of the nested components for toolbar also work inside of app bar so i'll give it the name e events and then close that tag and you can see it added this rather large app bar at the top so to style it we're not going to use it how it is out of the box but there are so many props that we can pass into this component and for our purposes and for a general top navigation there's just one prop that we need and that is the app prop so the app prop does a couple things including adding a fixed style to the toolbar so it'll stay there no matter how far down you scroll but it also adds the fixed property while still keeping the other content below it on the page while the app bar is at the top or while you are scrolled all the way to the top of the page so let's see this and now you can see that it's a more reasonable size but all of the content is still pushed below it and the position is now fixed so as we scroll the app bar will always stay there okay so now i'm going to add the button the create event button so i'm going to come below the title add a v btn and i just want this to be a regular button for right now again there's a lot of button props that i can use but i'll just keep it plain with the default material styling create event close that now the button is kind of on top of the logo here and i actually want to bring the button all the way over to the right side of the nav bar and there's a shortcut for how i can do this and arrange things on the page in beautify i could absolutely use something like flexbox classes but instead i'm going to use a special beautify component called v spacer and now you can see the button is all the way over to the right here and that's because v spacer when it's put in the middle of two other components it acts as if you put the justify content space between property on the parent so basically it pushes component 1 and component 2 as far away from each other as is possible in the layout and the last thing i need to add to this nav bar is actually the search box which i want to put on this side over here next to the title so in the beautify docs i'm going to search for a text field so there are lots of different options that i can use for the text field here and just copy a regular text field and i'll paste it in here a little bit of cleanup first i'm also going to get rid of the label here and unlike the button if i go to the browser and see the text field you'll notice that it's not aligned really well by default it doesn't look really nice so there's several props that i need to use here to make it a line in the nav menu so i'm going to update this placeholder to say search and i want to give this just a little bit of space away from the logo so they're not brushing up against each other so i'm actually going to add a built in beautify class here on this text field of margin left of eight and since these are in four pixel increments for vidify so that's 32 pixels that should be a pretty nice margin i also want this to have a border around it not just a single line underneath the text so i'm going to give this a prop of outlined and then also rounded so this corners aren't squared that looks much better but it's still way too tall and it's not vertically centered at all fortunately there are a few props that i can use to easily fix that first i'm going to make this a bit shorter vertically so i'm going to give it the dense prop and then hide details and see how that looks and i think that actually looks pretty good now i just need to shorten it or make the width smaller and add a search icon so i'm just going to add a quick style tag to set a max width for this element and i'm going to set it at 350 pixels that looks pretty good now if i go back to the beautify docks i can see some examples of icon usage so there are different ways to append or prepend icons and let me go to an outlined example so you can put it before or after the search box but i want it inside of the search box so i'm going to do prepend inner or even try append to the end of the search box and see how those look and if i look at the code here i can see that the props i passed to know where to put the icon so prepend inner icon etc give it some space here prepend inner icon the name of the icon i want is one of the material design icons that i already set up when i set up vuedify i'm going to do mdi for material design icons dash magnify save that and there it is the search box with the search icon at the beginning and i think that looks pretty good for now next thing i need to get rid of these boilerplate components and add the tabs to the interface here i'm going to use the v tabs beautify component and you can see it's just basic tabs that switch with an underline so i'm gonna come here and copy some basic tabs and now in my code i emptied out the index dot view file and i'm just going to paste those tabs in here and in my browser you can see i have tabs now now let me just do a little bit of layout cleanup here so i'm going to add a container and a row like i have on the other pages and give this some offset okay accidentally did six change this to three and that should be in the middle now so now i need a way to capture what current tab i'm on and i think i do that through v model here let me just check so here is a playground example where it shows switching tabs and if i look in the code so this this models to tab and that starts off as null so it'll just default to the first tab and i can see also here i might want grow to stretch my tabs out and fill the width of the page and i can also use some of these other things if i wanted them centered they make it easy to do that but i think i'm going to try grow for now so back in my code i'm going to come to tabs and zoom in a little bit here and i will do v model and just model to a tab variable just like it showed in the docs and then also set the grow prop there and now come down and add a data method return an object and i'm going to set tab equal to zero which should be the first tab all right so here are the tabs now and if i look in my vue.js dev tools i can see that tab is zero and now tab is one tab is two etc okay so in a minute i want to watch for that tab change but first really quickly i'm gonna set up some cards to display below the tabs so i'm going to come in here in beautify and look for cards and grab this card because it has an image and some text and even some buttons so that's the exact layout that i want and i'll just copy this the card and i'm going to come below my tabs and then just paste in that card okay and i'm going to leave most of this as a placeholder i just want to remove the text that's in front of the image and then i'll make this self-closing okay it shows a basic card below the tabs and i'm going to be using this to set up a watch function and change some of this data so in my options object down here i am going to add a watch object where i'm going to watch for the current changes of this tab variable in data so i need to call my watch object the same thing here i'm going to call it tab and then in the method i get the value passed in so i can take the value and every time tab changes it's going to call this method because it's watching for changes on that tab variable and with a watcher i can call other methods from inside here so i can say if tab equals 0 then i'm going to say show all events and that's a method that i'm gonna make actually it has to be this dot show all events and for right now i'm just gonna put one else here and say this dot show events by type and now i'll come down here to methods create the methods object and i'm going to create those two functions so show all events as a function and then show events by type and let me see if this is working i'm just going to console.log here and same thing here okay it says tab is not defined and that's true it needs to be this dot tab so if i come back here it shows all and then oh right it is an empty string i was going to say type here so the methods in watcher are working that's great now i need to query here for the graphql data on the backend so that i can show the data as cards in this application so to set that up i'm going to come down to the grid some server.js file and if i look inside the grid some docs i can see there are examples for how to get data from various sources in my application like if i wanted to pull in markdown files or google doc files but i'm going to be importing from that strappy api that i created and to do that i need to make a regular api call so i'm going to copy this this api.loadsource method that gridsome gives me and then first i'm going to stop my server and then install axios while that's installing i'm going to come here and i don't need these empty methods going to delete those and paste in this load source method and then at the top i do need to import axios and to do that i need to use the require syntax so i'll say const axios equals require axios okay and now i'm going to point this api call to my actual strappy api that's running so that's on localhost 1 1337 and then the specific call that i want to make is to the events endpoint so i can get all events back from that and that's going to come back as a big response object and then the data is actually going to be on response.data so i can go ahead and pull data out of the response now let me rerun my server really quick run develop okay i'm getting an error here and let me see okay so the problem here was because x accidentally used https instead of http so now that i changed it to http for localhost everything works just fine so in my graphql schema you can see here that there are types that i can query so for example the type that we saw earlier was the type metadata and on that type i can get different information like site name site description and so here i'm going to be doing the same thing only i'm going to have a type of events and then i'm going to loop through those events and basically add nodes so this is almost like array.push so this collection i'm creating you can think of it like an array in graphql and then i add nodes which adds each object of data that i have so i'm going to loop through data and actually just as a matter of preference i'm going to set the type to be singular and then i'm going to loop through event of data because data is the array of events that i'm getting back and then i do collection dot add node so if you look at the data that i'm getting back there are a lot of different pieces of information here and i definitely don't need all of them so i'm just going to take out the ones that i need specifically which will be all of these price duration date description title is required by graphql as is id and i can add whatever custom fields i want for image these are kind of deeply nested but i'm also going to grab the thumbnail via just the url and then i'll grab probably a medium image via the url as well so i already have id and title and that should be all of the information that i need so whenever i update that server.js file i need to restart my grid sim server so if i look at my graphql playground i can see that i have this new event type this is the event type that i just added and i have id title description price everything that i added including the image so let's write a graphql query for events here to test it out and to get the actual data from events or from the api that we've already pulled into our app i can use the all event query which basically lets me query all of the items that i have of type event and now these next two terms are specific to graphql so edges you can think of this as the array of events and then node is each individual event and now i can query for any properties on event that i want i can see from the schema i have id title description so let me just start with id and title so now if i come and hit the play button and now you can see i got an array of all of my nodes here now you might be wondering why i couldn't just query all events and then just get all my events back why do i need edges and that's actually because in graphql i have other metadata on all event that i can ask for like page info and total count oh right i need subfields here and i can use this let's just say is last and this is pretty much useless information for this api but i can get back the total count of items here okay so i'm going to get rid of that and now in my node i want to get the rest of the information because i'm going to copy paste this query into my application and that's all of the information that i have so i'm going to copy this query and i'm going to add it to my index page so it should be below template and above script and i'm going to add a page query tag and paste in the query okay and the only change i want to make here is give a name to this query and so this events name here is actually what i'm going to use in my component to loop through the events so let's look at that now my loop i actually want to be in my card here and i'm actually going to get rid of this card that centers it or that class that centers the card and i'm going to change this to 300 wide and now above that i'm going to add a v4 loop to loop through all of those events and display them as cards for edge in and now again because i used page query here i have access to dollar sign page here and then dot events dot edges and of course i'll need a key here since i'm looping so i'll use a unique key just the id of the node so id okay and now let me put the data from the event inside of the card so we can see it show up on the page so i'm going to make this image dynamic instead of having a hard-coded url now these event urls are only partial urls so i'm going to have to prepend the server and port so let me add a variable in here so be edge dot node dot thumbnail okay and then below the thumbnail i do want the title v card title and this will be edge dot node dot title the card title the subtitle is going to be the date so that will be edge.node.date and then and now i don't think i'm going to have any text here so i'm going to get rid of this so i'll look at the buttons in a second okay cool it is in fact looping through all of my cards now i think it's just not wide enough i'm also zoomed in here so i have to make sure that these are wrapping in rows update the buttons and also update the time here but everything else looks good alright so on this card i am going to add a class and i'm going to give it a margin top of five since all of the cards are pushed up against each other and the top card is actually up against the tabs and now for the buttons so i'm gonna get rid of the second button here and with this one i'm just going to have a more info button so you can see more info about the event and then i want to display these cards in a row so i'm going to need to put all of the cards in the same container and that container is actually going to be a v row which by default gives me the display property of flex okay cool so it is wrapping for me that's great now i do want to space these cards out so they're not right on top of each other so for row i am going to set another flex property and since rows are already display flex i'm just going to add justify and i believe it's space around and these are all styling classes that beautify gives me and yeah that looks good the only other thing i'm going to change is i want these cards to all be the same width so instead of max width i'm just going to set a width looks really good so in the strappy api i have two categories here i have music and coding and i want to use the tabs to filter between all events just one type of event or the other type of event and we already set up watch for this a minute ago so the first thing that i'm going to do here is hook up these show all events and show events by type these two methods that are called from my watch function so just like i have up here i have access to page page.events.edges i also have access to it inside of my vue.js options here so what i'm going to do is inside of data i need to have a separate events array that will display the events however i'm filtering them now i can't just do this dot dollar sign pages here because when the vjs instance is looking for data the graphql query hasn't injected this dollar sign pages object yet so i don't have access to it and it's going to give me an error so here i'm just going to put an empty array and then i'm actually going to get the data in this component by using a life cycle hook called mounted to make sure that the data is ready for me when i'm asking for it so here is where i can set this.events equal to the array of my actual events which will be this dot page dot events dot edges and now i can filter off of this array and i'm going to copy this real quick because inside of my show all events method i just want to show all events so i'm going to set this out events back to all of the events in case it has been filtered by something else and in the show events by type this is actually where i'm going to do some filtering and i have three tabs in this component so tab one will be all events tab two is going to be music or maybe live music i guess it's live remote e-music and then coding events so it's going to be tab 0 for all events tab 1 for music and tab 2 for coding which matches perfectly up with the categories in my api so if i look through all of the events i can see that this community music night event has an id of one and then i can see iot hack which is a coding event has let's yeah an id of two so coding is category id 2 and music is category id 1 so now i'm going to filter in here in the show events by type method so i'm going to start this method by doing this dot event which i will be setting to this dot dollar sign dot events dot edges and then now i have to loop through these so since it's an array i can use the filter method from javascript and i will get an event object there or i'll call it edge to keep it consistent with what i've already written and now basically i need to return true whenever the type of event matches what i'm filtering for so to do that i need to know which type of event and instead of looking for this dot tab i'm already passing in the value here so i might as well pass it through to show events by type and then i will receive the value there so i will return whenever edge dot node dot category is equal to the value that i have passed in which for music events that will be a one and for coding events that will be a two as you can see tab one and tab two now to get this i need to be pulling in that category attribute into my component so i'm going to have to update this file to get category and then i am also going to have to map the category and i'm also going to have to make the category attribute available from my grid some server file i basically need to add category onto these nodes so category and then in category i'm gonna just grab the id from it not the name or anything else so event dot categories and then i'm just going to assume there's always one and only one category associated with an event so i'll just grab the first one so event dot category zero and then grab the id off of that and now let me restart the server and let me see if the filtering is indeed working and it's not working so let me try to figure out what's wrong if i look first in the console doesn't look like there's any errors so in the view js dev tools looking in the index file i can see that the filtering actually worked there's two items in the array right now and when i go to coding there's now four items all events there's six items so filtering works but the page isn't displaying the right thing so if i come back to index go up to the page it's actually because i'm looping through page.events.edges which never filters which never filters so i'm going to get rid of all of this and just loop through the events on data everything else should be the same now if i refresh my page it is now filtering now i only have two events i have four coding events or i have all events so filtering watch all that stuff it's the exact same methods that i would use in a regular vjs application the only difference is how i receive the data in the component through that graphql data layer now there's one more quick thing that i want to fix here and that is this date so i'm going to stop my server and npm install moment which is a javascript library that makes it really easy to format dates and has tons of helpful date methods and now i will rerun the server and i'm going to pull moment into this component in my script tag i can import moment from moment and now i'm going to create a special method or custom method here for formatting the date so i'm going to call it format date pass in a date to format and then i will return moment pass in the date to moment and then moment has this method called format i'm going to format and this is all in the moment documentation all the different ways that you can display a date this is just how i'm choosing to display it with the month day year hours minutes and then because i live in america i'm going to do am or pm and now the only thing i have to do is take this format date function come to my date and then pass in the date to the format function and that should return a properly formatted date which you can see now august 9th 2020 etc now how would i click on one of these cards and go to a page specifically for that event so i mentioned templates earlier and that's what we're actually going to use for this so in source there's the templates directory and i'm going to create a new file called event.view and now in this file it's just a regular view file so i'm going to add the template tag and i'm going to pass this into layout which is my default layout that i'm using everywhere else and then inside of that i'm going to do an h1 tag and that's going to have my event title inside so let me close the layout and now i'm going to need to get the data inside of this component for a specific event so i need to use another page query here to make a graphql query and how do i get the data for just one specific event so i'm going to come into my graphql playground and just write the query here first so i'm going to do query and then the curly braces and then i need to let it know what i'm going to query so i can actually tell it what type i want to query because i just want one item i don't want an array of items so i can say event and then i need to pass in the id of a specific event so i'm gonna say id is five and now what items do i want to get back from that one specific event and i'm to say i want the id and the title duration that's fine and now if i click the run button i see i get back all of that information i don't need to do edges and node because it just finds one particular node based off of the query because i'm just looking for one and then just returns that to me so it's a little bit simpler and i'm going to copy this come back to my event event.view paste it in i'm going to add a few more things on here too like price date and image and then at the bottom here i am going to add a script tag really quick and this is basically because i want to set the page title for each event page to be dynamic based off the name of the event so i can do this through grid sums meta info object or method and i can return title this dot page dot event dot title and this will set the page title to be this title variable okay now i've created a special template for this event one thing i want to do really quickly is just display something on the page so i can make sure it's working so page dot event dot title and now how do i get to this page so let me go to the grid sum server dot js file and i forgot to start recording but this path is basically what i need to add so i'll explain that in a second but that's why it's already typed in there so here i need to tell it for this collection for each type event in graphql i can give it a path of where that event page will be and since there are many events it needs to be a dynamic path name so i'm going to say slash events and then id so the id of the event and each event will be displayed at that page with its own id in the url and now you can see that i have added path here on each node that i'm adding in the collection i'm giving it its own path with its individual id so now when a user hits this path this page will load and show the title of the event so let me restart the server to see that working and in the app i'm going to go to slash events and then an id of any one of the events so i'll do five works and you can see that it shows the title of the iot hack which is the name of the event so there's a couple more things that i want to do with just formatting the event pages and one of them is actually in this layout template so in my pages like actually i don't need the about page anymore so let me delete that that was just there by default so in this index page i have container row and column to put everything in the middle of the page but i'm going to be using this on a lot of pages so i'm actually going to copy this and go to my layouts default and now around this slot i'm going to add the container row column and let me close that and now i don't need to have these things on specific pages so let me go to the index page and get rid of those extra elements now because now they're part of the layout so let me get all of these okay so i'll only be using the nested rose get rid of those three and now this is set apart from the edge in the top a little bit more i also want to display the image for the event so i can display an image tag use source equals then use graves inside so this will just be the url of the image so the localhost these are on my server so localhost13337 and then i will pass in the path of the particular image that i want to display which will be page dot event dot image and that should display the image and then i will just display the description below this so i'll do page dot event dot description then i have to close the image and there it displays okay i think that actually this particular event might not have a description let me check oh right i can't click on these yet so let me actually make these clickable first and then i'll check so if i go to my index page i'm going to add an app click on the button here to capture a click event and then i'm going to use the router methods that i have available from view router in gridsome so i have router dot push and then i can do slash events and then i need to pass in the id of the event in the loop so i'll need to pass in edge.node.id let me see if this works hackathon okay so it displays the hackathon let me go do another one jazz jam so it looks like the description just isn't showing up so let me go to events and that's right i'm not importing description so let me now query for description make sure that's spelled correctly it is and now if i go it shows the description at the bottom and now there's no way to get back from one of these pages so i am actually going to add a link to this events title in the corner here and that is found in my default layout component i have this toolbar title let me put that on a new line and i'm going to wrap that in a link so like i mentioned before grid some has its own link component that's kind of like view router's link component where you do two you set this to prop and it will route inside your application so i'm gonna say two and then just forward slash to wrap to the home page and now i can click on it route to the home page real quick i'm going to fix the styling on this link just come to the bottom here make a style tag and i can reference the tool bar with double underscore and title and then i want to reference the anchor tag inside of that basically get rid of the underline so text decoration is none and then i also want to set the color back to black and that looks much more like a regular title so if i come into an event i can go back by clicking on the title in the nav bar so now i'm going to hook up the search bar if this were an application that i was going to deploy somewhere i would use a library like js search or flex search or even an api solution to make api calls to query for the data that i'm searching for but for this i'm going to do it the easiest way possible and that's by basically filtering by the name or the title of the event to do that i need to add a v model so i can capture what i'm typing into my search here so i'm going to do v model and i'll just call this search text and now if i scroll down i need to create a script tag to model this so script and then the data method return an object and i'll put search text is an empty string by default and now this is in my default layout component and i need to get it into this index dot view component so there are several different ways of data handling and management in vue.js you can pass things around component to component use events that are built into view and since i'm not using view x for state management in this application i think the best option would be to pass it directly from default.view to index.view and i can do that actually passing data through the slot so i'm going to come up here and this slot is where all the pages are displayed so i can actually pass props into the slot that the pages can see and that's what i'm going to do with search text i'm going to v bind my search text equals search text variable now from my index dot view component i can receive that using the v slot directive so i can do v slot equals props here but instead of using props just as an object of all of the props i'm actually going to just pull out search text from props and now i can use search text anywhere in this component but i want to be able to call a method to filter using search text so i'm going to come down here actually to events so i'm looping through events so i'm going to have to update events to consider anything that might be in search text so i'm going to create a getter events method so i'm going to say get events and then i'm going to pass in the search text and so get events is going to return all events and if there's search text then it's going to filter the events based off of the search text so let me create a method for this in my methods after format date i'm going to say get events pass in search text and then i need to return an array because i am looping through this still so i need to return this dot events dot filter and then just like this other filter up here i'll keep the same syntax so i'll say edge and make it an arrow function and now this function i'm passing into filter needs to return true or false based off of whether or not i'm going to keep each object in the final array that i output so i'm going to return edge dot node and then i'm filtering or searching by title so i'm just going to consider title and then to lower case i don't want this to be a case sensitive search and then i can use the javascript includes method for strings basically i can find out if this this string edjado.title includes any of the text that i'm going to pass in so i will call that with search text and then with search text 2 i'm going to have to to lower case that as well and that should filter by the search text so let me see if that works and let me just start typing in that's awesome it works perfectly and based off of what tab i am in it's just filtering by the current array of events so nothing else because it's just a getter method it's not mutating the state of the component so i can update the search text and it has no effect on the actual array that i am displaying on the page if i get rid of the text one more thing that i really should have with search text is it should be clearable and i can add that with a clearable prop here so in my v text field i'm going to add a clearable prop and now if i type something in here you can see an x appears the only problem is when the x clears the search box the page doesn't update until i start typing again so one way i can fix this is if i look in the text fields documentation here for vuedify i can look in the api for vtext field and go to events and i can see all of the events that i have available to me so i'm going to take this event which is a clear event so when they click the clear button basically this event is emitted so i'm going to put that event right here at click dot or colon clear and then i can run some piece of javascript whenever this event occurs and what i'm going to do here just to make it simple is manually set the search text equal to an empty string again and that is going to trigger an update from the function so that it will re-filter the array so let me try that out i'll do hackathon and now clear and now all of my events come back so what about the create event page like it implies it would be a form page where you could fill out information and create a new event if you look in the grid some docs it recommends some form submission services and basically we could do the same thing posting to our back end which is strappy like it shows here we could have a handle submit method in our vjs and then just make a fetch request which is posted to strappy or if i had something like a contact form i would probably use one of these options like formspree but as far as hooking up this post request and deploying this application you are going to have to check out my channel i will be posting some videos on deploying applications and i'm going to be deploying several of the applications that i have built on my channel over the last few months so if you want to see more grid some more vjs and more other related coding topics then make sure you check out my channel faraday academy
Info
Channel: Traversy Media
Views: 67,629
Rating: 4.9079423 out of 5
Keywords: vue, vue.js, gridsome, strapi.js, faraday academy, vue gridsome
Id: vB6rmWCmANA
Channel Id: undefined
Length: 89min 16sec (5356 seconds)
Published: Mon Aug 31 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.