Learn Vue.js - Full Course for Beginners - 2019

Learn Vue.js - Full Course for Beginners - 2019

SUBTITLE'S INFO:

Language: English

Type: Robot

Number of phrases: 3111

Number of words: 23396

Number of symbols: 97782

DOWNLOAD SUBTITLES:

DOWNLOAD AUDIO AND VIDEO:

SUBTITLES:

Subtitles generated by robot
00:05
welcome to the course my name is Gwen and I'm a software developer here is the itinerary for today part 1 we'll start in the browser to get a feel for the syntax and part 2 will be on a local computer building apps as you regularly would along the way we'll cover different bits of the view API so you can get started right away first let's define what view is on a basic level it's a front-end library to help you
00:36
build JavaScript applications now view jeaious is more robust than something like jQuery since it gives you specific recommended patterns for code organization although it did borrow a lot of good ideas from jQuery angular react and others it's usually not found in the wild by itself you'll see it used with lots of other libraries and combined to make sort of a framework an alternative to react angular and others and we'll cover many of these libraries
01:05
today so let's get straight into it I'm here my browser at jsfiddle dotnet is just another place to put front-end code and I'm going to try hello world so this is if I was just writing a plain HTML or jQuery application I might put something like this so how do I attach this to the view instance here I've reloaded the
01:39
view library so I can just choose it from frameworks and extensions I'm just pulling in the latest version and from that library I have a view instance so I can instantiate it like this and then pass it an object of options the only required option I have to set is element so which element in the Dom do I want to attach my view instance to I'm going to attach it to root and then of course I need to have a root an element with ID
02:10
of root here so now my view instance is attached to this div in the Dom if I run it of course it doesn't do anything different so let's make it do something different there's also a data object I can use and I can populate this with variables to use in the Dom so I can say data
02:38
breeding now how do I put this in the dome if you have something called double mustache mustache syntax so anything inside of this inside of these double curly braces you looks at and will parse as JavaScript so view comes down here and says okay I have a variable in data called greeting and so I'm going to
03:12
render the contents of the variable we've run this again it changes the hell of you another important concept in view is data binding view uses two-way data binding through a directive called Z model on an input when I put V model it binds it to a variable in the data object that I give it so in this case I'm telling you to bind this value of
03:44
the input to the greeting variable from data if I run this everything inside of my input is the same as the greeting variable and then if I change it it live updates extremely simple V model is something called a directive there are a lot of directives in view and they're used to interact with the Dom let's look
04:16
at another common directive v if v if evaluates an expression to a boolean value either true or false so let's start with something that we know is true so if one equals one you're telling view to display this div and render it to the page yep so this
04:53
isn't so useful it's usually used in combination with data attributes here so let's make a new data variable we're gonna call it count so if count equals one then display this div to the screen so I'll put I change this to count equals zero and of course
05:28
it won't display to the screen now there are other directives that you can chain called V else if and the else just like an if-else statement so let me change these and let's save count equals two so this
06:13
is pretty self-explanatory if count is one nope if count is to render this anything out other than that render V else Oh put two it's gonna render red and so on now the thing to note about V if these divs if they're not true they don't get rendered to the Dom at all now this might be the behavior you want and many times it is view also has another
06:49
directive called V show so let's call this V show and we'll just do the same thing if count run and it's green now
07:22
this time if count is two of course nothing displays here but it's actually still being rendered to the Dom just with display:none set in the CSS so if you look in here to kind of dig in but you can see that there's a div with green inside this are same div up here and it's set to style display:none so
07:55
it's still in the Dom here and so sometimes you want to use V if and sometimes you want to use V show it depends on what you're doing in the application and if you need better performance if you're constantly adding and removing things from the Dom so let's look at some more directives I've already typed this out to save some time is just an input with a submit button you click it alerts and also an email variable that is bound through the v-model directive to the what's entered
08:28
into the input the view has this directive called V blind of the bind can take an HTML attribute like disabled that works in vanilla HTML and parse it as JavaScript so email button links will say is less than two so what this does is the regular HTML attribute disabled would disable this button but we're
09:00
telling view to parse this as JavaScript so we're gonna take the email length and the button will be disabled only if the email length is less than two if it's greater than 2 then the button will be enabled so let's run this and you can see I can't click on it it's disabled but if I type something here now it's enabled again so you can do this on many different attributes not just disabled and there's also a shorthand which is
09:30
what you usually see in view applications so it will be just whatever HTML attribute preceded by a colon and that shortcut for saying V bind colon because it's so common in view now another use for V bind that's common is to dynamically add classes so let's do colon the shorthand for V bind class and
10:03
then there's two different ways of doing it I'm gonna start with the first syntax which is called object syntax so I'm going to dynamically add this read class and I'm gonna say if the email dot length is less than 2 I want to have a border a red border around this input box so let me run that
10:35
and I have a red border and as soon as I get past to where I get to or greater I don't so that's how you can dynamically toggle classes so there's another syntax used if you want to toggle in between two different classes which is array syntax so we can use just a regular JavaScript ternary here so you know about length is let's say if it's less
11:08
than two then we're going to use the class red and if it's greater than or equal to two will be the class screen so let me run this and we had the class red and now it toggles back and forth in between green there are several other directives in view these are a bit less common but I just want to mention some of them so we already know that we can
11:41
put variables in the Dom using the double mush deston mustache syntax if I run this I can type and it shows up I can actually do the same thing using a directive called V text put paragraph tag the text equals you know and then just close the tag so if you're used to jQuery you'll be used to the dot text
12:12
that it uses to put text inside of an HTML element this is doing the exact same thing so if I run this it does the same thing as using double curly brace there's also V HTML which will parse it and we'll just put text inside but it will parse it as HTML similar to the HTML and jQuery so if I type stuff in it does the exact same thing but I also type in HTML tags and it parses it
12:46
as HTML so what if you want to render something just once a static HTML well view has another directive called V once say once and put the email in here just to compare I'm going to copy this and put it outside of the one's so let me start with something initially here so as I update this it only changes in
13:36
the second one because it's frozen and just set as the static HTML of whatever it was initially the second one will still display and update as you change the v-model for that variable so let's look at looping in view I'm just going to clean this up real quick all of this and let's make a list unordered list it's no I and the directive to handle
14:13
looping in the Dom in view is called v4 so let me come down here and get something to actually loop through which is an array of cats I've already written paste it there and the syntax for this will be you need to take your red cats and you're gonna say item in items so it will just be like a four in loop in JavaScript so you'll say cat in cats and
14:51
then during every iteration of the loop you'll have access to the cat variable which will be per index in the array so I'm just gonna put cat here and run this again and it comes out with all the different cats in the array so of course in the first iteration it displays in Li element with the first cat inside which
15:22
is KitKat that index 0 and then it moves the loop moves to index 1 and then index 2 and song is on and if you look in the dev tools so you can see it has the full array there now you can also do this with objects of course these are just simple objects with one key value pair each so now cat would equal this object
15:52
with the name inside so to display the cat's name now I'd have to do cat name run it and I get all my cats great so does more we can do with looping and there's more we'll get to later when we're looking at local applications but that's pretty much how it works so let's look at functions now what if we wanted to add a new item to this array so I'm just gonna add
16:23
something similar to what there was before and put the model little new cat and button so I'll add a function to the button in a second let me run this and
16:52
it renders my static HTML that's good and let me add this new cat so this is modeling my new cat that I'm gonna add to this list so I need some kind of a function to add it for me and I can do that with a directive called V on on click so when I click this button I want it to perform an action in this case I want it to run the function add
17:35
Kitty which we're about to make so the data object is just for variables so to put a function here I need to add one called methods and this is another object with functions inside so add Kitty oops
18:02
kitty which is a function and I'm gonna need to push a cat onto this array to add it to this array so I can access any any data variable inside of a method by doing by using this so this dot cats will access my cats array in data here so this dot cats dot push and then I
18:38
want to push my new cat and my new cat I also have access to on this so I can say this dot new cat and I have the new cats name and of course this would work if we had just a plain array but we actually have an array of objects so I'm gonna put this inside of an object and then say name is this dot new cat so this will push another object onto this array
19:12
so let me see if this works ran it let me add and I can't press ENTER right now but when I click the button it adds it pushes on to my array perfect of course it's kind of annoying click add every time so what if I want it to respond to and enter as I'm typing so I can quickly add more kiddies I can actually add another event with V on
19:43
again but in this case I want V on key up and then equals add kitty so I want to run the function add Kitty on Kia so let's run this and see what it does so unfortunately though I didn't tell it which key up so any key that I press it's just adding a new cat for each one which isn't the functionality that I
20:14
want so I can modify this key up by saying key up dot enter let me run that there key up enter so I have to hit enter and it adds it to the array which is perfect unfortunately it's not really the functionality that we want to leave the same cat in the input box so how do
20:45
we clear the input box we can just set new cat this dot new cat equals an empty string we've already pushed the new new cat so we don't need it anymore and this new cat is fine to be emptied again so let's run this there and now it empties ready for more cats so there's many more events and modifiers that you can chain on to
21:29
events for example view has an API for chaining things on to the click event you could do dot prevent which means prevent default and you can also do stop for stop propagation basically all of the common things you might do that are associated with that type of event which is super useful I want to show one more shortcut here and this is what you'll normally see in a view application instead of Veon because it's so commonly
22:01
used they have a shortcut to just do at so at click and then you can do this with any type of event anywhere you would use beyond so you can say at KeyUp let me just show that this still works and it works fine both ways work this is just adding a shortcut to it so let's say you want to update something that's rendering to the Dom view has something called filters so I'm just going to
22:33
write a simple filter to illustrate what it does and I'll come down here after methods I can add another object and this one is similar to methods it's an object of functions and I'm going to put the function capitalize function actually value here and I'll return the value but I'm going to change it to
23:12
upper case view will parse this as JavaScript with cat name and then it will pipe it to this capitalize function which is a filter so it doesn't change the actual value stored in the view state here in the data property so all of these names will still be lowercase but just the display on the Dom will be piped through this capitalize function
23:45
and it will come out value dot to uppercase so if you run this so I actually misspelled filters here I'm gonna add an S and there you go it filters through the capital I so you can also pipe these so I'm going to add one more key defi and I'll make another
24:10
filter here and I'll return the value Y so when that it returns Y on the end if I piped it the other way the Y would be capitalized really this isn't used that often in view in my experience it's just a good thing to know about for when the need arises another set of methods in view for updating what's seen on the Dom are
24:48
the computed methods so let me get rid of filters real quick and this filters block here and I'm gonna add computed instead and I'm going to use the same and scroll down and I'm going to use the same method so let's get a PHY the cat named function this time the function doesn't
25:31
have to take anything so let's say if this dot new cat which is our cat name that's entered in in this input box so if that the length of that is greater than one I'm going to return this stop
26:00
cat name plus y and let's display this in the Dom to the fire game and I'll put a break after so you probably noticed the connection that view whenever it sees a variable inside of the double curly braces it looks down here at the data property and the methods and the filters and the computed and tries to find a match for it so let's run this there we go
26:45
and as I type well it's adding the Y for computed but it's coming up with undefined and that's because I misspelled the variable so you put a new cat there and run it again yeah and that should work so later on you'll be using computed a lot when you deal with view X it's also extremely useful if you have a lot of logic in the
27:19
Dom let's say you're doing a lot of computation or updating inside of this block then you could clean it up take all of the logic outside of the Dom here put it inside of a computed property and then just display it in the Dom like we're doing so let's say you want to update something that's rendering to the Dom view has something called filters so I'm just going to write a simple filter
27:48
to illustrate what it does and I'll come down here after methods I can add another object and this one is similar to methods it's an object of functions and I'm going to put the function capitalized function actually value here and I'll return the value but I'm going to change it to
28:25
upper case view will parse this as JavaScript with cat name and then it will pipe it to this capitalize function which is a filter so it doesn't change the actual value stored in the view state here in the data property so all of these names will still be lowercase but just the display on the Dom will be piped through this capitalize function
28:58
and it will come out value dot to uppercase so if you run this so I actually misspelled filters here I'm going to add an S and there you go it filters through the capital I so you can also pipe these so I'm going to add one more key defi and I'll make another
29:24
filter here Y so run that and it returns Y on the end I piped it the other way the Y would be capitalized really this isn't used that often in view in my experience it's just a good thing to know about for when the need arises let's talk about custom components view has a component architecture that lets you reuse bits of
30:06
code just like most modern single page application frameworks so let's illustrate this I'm going to create a new component using view dot component and I'm just gonna call it cat list and then I pass it an object of options that's it there's a template and I'm just going to do a multi-line string
30:36
with let's say for right now and actually a list should be inside of you now how does this work what's this I'll have to attach it to my view instance so I'm gonna say component and then give an array of components my components name is cat list
31:16
now let's add cat list to the Dom so to add any custom component that you make you can just add it by its name and run it and you can see cat down here you can also pass in logic and variables so let's pass in our cats array and display the array through the component the way to accept variables in a component is through something called props I'm going to pass in the cats array I'm going to
31:48
say props cats actually this and I'm gonna pass in cats and then here I can use a V 4 V 4 so here I actually have to pass in cats so I'm passing in
32:32
cats but if you remember here I have to add V bind for the shortcut which is just a colon because if I don't add that it's just going to treat cats as a string when it gets passed into the component instead of treating it as JavaScript and then looking in the data property and getting the array so now cats is set to the array of cats and if I run this again it's the same array and
33:03
it adds on to both of them so the idea of having components is that they're reusable modular pieces and when you're developing view locally view CLI brie it's a really nice project with you with a modular architecture that kind of handles this under the hood for you to wrap up here I just want to talk quickly about view lifecycle methods view will trigger certain functions to run which can be very useful when you're
33:32
developing an application so I have four functions here created mounted updated and destroyed and they're just logging things I'm gonna run this and if I look at the console it shows created when the component is created when it's mounted as it Adamic runs mounted now it's been updated because the state and the data object has been updated now for destroyed it's a bit
34:07
harder because in the small applications instance never leaves the Dahmer's destroyed so I'm going to take a function to call destroy so I'm basically setting a timer for 5 seconds and after 5 seconds it's going to call app dot destroy because the view instance is set equal to the app variable so this will destroy it let me
34:37
run this again so I see created mounted and then destroyed this also means I won't be able to update anything here because it will be just statically render at HTML as it is it's no longer connected to view there are many other functions that run including before mounted before destroyed and I think they're very well drawn out in the view documentation so view jeaious org the
35:09
version to guide and if you look at the lifecycle diagram section it shows you exactly when each function is going to be run during the lifecycle of the component so this is a really good reference and you'll be using these a lot as you develop applications next we're going to go over how to start developing applications with view CLI locally to create a view jeaious application we're going to start with the command line interface so if you come to CLI dot
35:44
view Jas org and click on getting started now over here on the left is a link for installation and it prompts you to NPM install - G view CLI globally so if you copy this command and come over to your terminal you can enter this and install view CLI I've already done this so I'm just gonna check my version my
36:17
version is three point one point one so now I'm going to create a view app I can do this with the view create command so view space create and then whatever I want to name my application which in this case I'm going to call it quiz so it takes me through a series of prompts mm-hm so if you'll notice the last one manually select so you can select routing testing linting etc the default gives you just babble and es lint and is
36:47
a pretty basic site on top this is a template I created which I'm going to talk about how to do later so for right now we're just going to pick the default to get started and see how it works it's installing all the dependencies this will take a few minutes and it creates a folder for you called quiz with your view application inside and now it also
37:16
tells me how to run the application so I can move into the quiz folder npm run serve and it's going to run my view application on port 8080 i'm gonna copy this go to my browser and it gives me a boilerplate application let's open up our
37:53
application and see the code I'm gonna be opening up envious code which is a free code editor and you can see by default it gives you a few config files package.json which is where you reference all of the code that you didn't write any third-party libraries and then the meat of the application is in the source directory and this is where your j/s gets rendered or your view gets rendered to the page so you
38:25
can see it's creating a new view instance like we did before the syntax is a little bit different but it's doing the exact same thing it's mounting it to a Dom element with the ID of app if you're wondering where your HTML file is it's in the public directory you can see your index.html and view is doing quite a few things under the hood that you can't see so it auto injects your script files so it creates a bundle out of your main j/s and all of these different view files it bundles them all together and
38:56
then it injects a script into your HTML file for you that's one of the really nice things about using view CLI you have all of this boilerplate and setup done for you like web pack and babel so you can just start building right away if you want to look at the view scripts these are the different scripts that view is calling to run your application locally or to build it for production or to lint it for you so let's look at the application from the main j/s it's importing this app view file which is
39:29
the entry point of the view application if you look at app view you can see that it puts a template this isn't created by view this is part of the html5 standard but it puts it in the same file with a script tag and also a style tag how view works is when you're building an application locally you create many different files each with their own template tag containing your HTML and then a script tag which contains the JavaScript interacts with that HTML so in that way
40:01
you can divide up your application into components and then put them all together they're all bundled into this main.js surrendered to the page so here's the first project we're going to be building it's a quiz application that keeps track of the number of total questions you have answered and the number you got correct the questions are pulled in from an API and displayed along with the answers the only user actions are to select an answer
40:32
click Submit and you also have the option of resetting the count of questions to zero when you choose an incorrect answer the color of the answer will turn red once you hit submit and the correct answer will turn green if you get it correct it will only show the correct answer that you selected back in our quiz app let's start making components first I'm going to delete this hello world view which will not
41:01
need and create two new components header view and question box top view which is where we'll display the question answers and the submit button inside of components the only required element is to have a template tag for HTML you don't really need script tag or
41:33
a style tag so I'm just going to put some dummy text in here question box and I'm gonna copy this for the header component and just put a header here so the app component is still expecting hello world so I'm gonna put our new components in here instead I'm gonna say header and header to be able to use the component in the
42:26
template section I need to add header here it's comma and then question box and now I can get rid of the hello world in image and I'm going to add the header here as well as the question box all right let me run this and p.m. run serve
43:03
and in the browser we can see we have both components a header and question box so before i update any of the components anymore i'm gonna install a third-party library called bootstrap view bootstrap view has a lot of built-in components and CSS already written so we don't have to worry about styling if you're interested to see more you can go to their Docs or see all the components that they offer like buttons
43:33
different form elements and they're rather nice layout and grid system which we will be using so to get started I'm gonna go back get started and copy this command it wants me to npm install view bootstrap view and bootstrap so I only need bootstrap view and bootstrap I'm gonna go ahead and copy it go to my terminal let me close this and get rid
44:05
of you alright now that that's installed I can add it to my project in my main JavaScript file I'm going to import view and then call view use to add it to my application so when you create view apps using the view CLI this will be in the main J's file you can add import bootstrap view I like to do my relatives Dependencies last and now I'm calling
44:38
view use bootstrap view of course this view use is just for the JavaScript portion of bootstrap so I'm also going to take the CSS and import it let me import bootstrap CSS and now I can start using these built in bootstrap components so let's use view bootstrap in the header component I'm actually going to go over to the view bootstrap
45:08
Docs and find the nav and the header is not going to be a real nav in this application but just for styling purposes I'm going to go ahead and use this I'm going to switch to two spaces here for consistency put a wrapper div in case I want to attach classes to it later also now I only want two items in
45:42
here I want to have the name of the application which would be something like fancy quiz app and then a counter for the number of correct versus total questions so I'm just gonna hard code this for right now and replace these with variables once I have that part of the app working so let me see how this looks let's run the app again and now oops now in the browser awesome
46:23
the only problem is these are links because it thinks it's an overview bootstrap thinks we're making a navbar so I'm just going to go ahead and disable these instead of active here I'm gonna put disable and disabled and then for the logo I just want to differentiate the style a little bit so I'm gonna make it bold also to offset the header I'm just gonna add tabs here
46:54
and this should auto restart yeah this auto starts in here so I'll go to my browser tabs added this line here and then I have my logo and the counter so the header component is done for right now let's move to the question box and go ahead and get that set up so the question box is going to use another view bootstrap component called the Jumbotron which is basically a page element that sets itself out of the page like this I'm actually gonna copy this
47:28
code with the enclosing div switch back to my code editor and paste it here just like before I want to have two spaces indent here just to note I always like to have this wrapper div around components because I like to make container classes for when I use sass or CSS so I would put something like question box container here and then reference this class to style this whole
48:01
component so this is a pretty plain Jumbotron you'll see it in our app and it's not exactly what we want because we want a question and then answers below it so in the Jumbotron Doc's we can actually use templates inside that will make the component look more like this so I can put the question on top then list the answers and have the submit button at the bottom and the submit button is another view bootstrap element for buttons notice it's perfectly fine to have more
48:32
templates inside of the parent template which is your component and you'll see libraries doing this using something called slots that we'll talk about later but for right now I'm just going to copy these go back to my component and I'm gonna put this inside so let's see what this looks like not too bad I am going to remove the header because we already
49:05
have a logo on the page and we just need to put the question here so this will be our question and then our list of answers will go somewhere here as well as a submit button and a button once you've submitted to navigate to the next question let's see what that looks like so we'll also have to get rid of these
49:36
which we don't want now let's see what this one looks like perfect question list of answers buttons now one more thing I want to do in view bootstrap before I get to the Java Script is set up a grid to kind of prevent these questions or the question box from going fullscreen so layout and grid system see the examples of how you can lay out a page with different containers in rows and columns for this I don't have different rows so I'm just going to use
50:07
so I'm just going to use the basic one here go back to my code editor and I'm going to go to here and I want this to wrap the question box component so get rid of the extra two columns enter and then just copy this paste and then in this column I'm going to tell it
50:44
so on a small screen or anything larger than a small screen I want to take up half the page which is 6 because bootstrap basically gives you 12 vertical columns so if you want half the page you can do 6 offset offset equals 3 and let me show you what this is doing so I'll inspect element here and the jumbotron in the question box container
51:16
is taking up 6 columns so if I hover over this you can kind of see that the yellow part is a three column offset from the left and the extra white padding on the far left is from the container so putting it inside a bootstrap container just automatically centers an element on the page and gives it a little bit of padding on either side so inside the container we have 12 columns we're using 6 and offsetting by 3 great now let's jump into the API for
51:46
the questions and start pulling some actual data for the application open TD be calm is a quiz API that we can pull questions from they give you a lot of nice options like you can browse through questions you can submit your own questions because these are all user submitted questions and they also have a pretty nice API by filling out this information we can actually generate an API URL to pull questions from so I
52:17
think pulling ten questions is good in category I'm just going to select animals difficulty any is fine any type a multiple choice just so the UI is the same for every question default encoding is fine so now it generates me this API URL I'm gonna go put it in my browser and I see every time I make a request to this
52:47
API it pulls ten questions about animals I think one kind of confusing thing with working with this API is that instead of putting all of these in one array they put the correct answer separate from all of the incorrect answers which is fine because we're just going to take the correct answer with the incorrect answers write a function to shuffle them all together and then match up the correct answer based off of what the user selects and of course every time
53:19
you hit this API it's going to come up with a different series of random questions that it pulls let's put the API in our application now so I'm in my app component now and I'm just going to add a function to pull in the questions and answers from the API so if you remember when we were in the browser using jsfiddle we covered something called lifecycle methods which are functions that get called automatically by view as components either get created
53:50
or mounted or destroyed etc so we're going to use one called mounted here function and in it we're going to use the standard fetch API which is a web standard and doesn't need a library to be imported so I'm gonna paste our questions API endpoint and then I'm going to pass an object an options object with the method I want to get
54:22
from this now that's all I really need but I'm going to add a dot then and take the response so I'm gonna say in the response when you use an arrow function here and say just let's console dot log this response in JSON format alright let's see what this does let's run this by the way don't mind any of this orange
54:53
text that's just which get branch I'm on and I'm trying to put different parts this tutorial on different branches I'm going to do and p.m. serve again no we have an error I was just complaining that I'm using a console dot log this isn't a JavaScript errors on linting error I'm actually gonna add this to my package JSON and all of my linting can fake is right here so I'm going to add
55:24
this as a rule here and say no console try to remember this is just for demo purposes if I were actually building an application I would probably want to have a warning or an error there just so I would remember to remove all of those extra console dot logs anyways it's running now so I'm gonna check it out in the browser of course nothing is different right now but if I
55:57
look in the console refresh and I'm actually getting a promise back which is good it means I'm getting the data back but we can't see it right now because I have to update my promise chain so let me go back to the code in app file I'm just going to return this long JSON and I'm going to change in chain another dot then so I'll just say it's JSON data and
56:28
let me wrap this just so it's more clear and then here is actually where I want to be able to access the data from my application so I'm going to create doesn't look like a habit data method yet so I'm going to create a data function and a comma and I'm going to return an object oops object now if you notice this is a
57:01
little bit different from how we did it in the browser the reason this is different has to do with some more complex features of JavaScript so we're not going to talk about those but it's basically required when you're making this type of single page application with a bunch of different components that instead of just making a data object you return an object from within the data function so it's a minor change so here I want to add a questions array which will be empty at first and
57:32
can be populated from the questions from the API so here I don't need to return anything but I want to set the questions this questions array to equal the questions we get back from the API so I'm going to set this top questions equal to the data we get back from the API dot results because if you remember the API gives us back two things it gives us a response code and then a
58:03
results array and the results array is where all ten of the questions we are pulling back are located I can save this my app still running so I'll test it in the browser and you can't see it yet so to inspect the data on our components we actually need something called Vijay s dev tools so if you google view dev tools this is the github repo if you scroll down you can see they have a Chrome extension a Firefox extension which I'm using Firefox right now if
58:34
you're using something else or you just want a standalone app that's fine too they all have pretty much the same functionality so I already have it installed and it comes up on my dev tools as view one of the things I love about view is that it has all its dev tools in one place we're gonna get into view X and different things later some other libraries you have different dev tools for different things that you're doing so under app I can see all of the components imported into App the child components I can also click on app and I
59:05
can see any data variables associated with that component under questions I can see I we have all ten questions that we pulled from the API and it's in the same format that the API showed us with the incorrect answers and then the single correct answer by itself so the next step here is to display the question to the screen so let's go back to our code I'm back in the app component and I want to be able to display the question from this
59:36
question box component so I'm going to have to pass it from the app component to that one and I want to pass just the question that we're on so as you're clicking next through questions I just want the question box component to know about the current question so I'm gonna keep in index of the question here which will start at zero and then view lets me pass data
01:00:06
variables and methods to my child components by using V bind with custom attributes so I can say the question I want to pass equals my questions array and the index so just the current question that we're on and then eventually we'll be able to click Next and this index will increment so
01:00:36
question 1 question 2 etc now if you remember the structure of our data off of each question off of each question so this is one question this object we have the correct answer in correct answer and the question so we have to get the question text off by using dot question so let's do that in the question box so I'm going to come here
01:01:10
and remember the double mustache syntax to use variables so I'm going to do question which is passed from the comparing component and then I have to do dot question so maybe it would be more clear if I did let me change this to I guess current question make it more clear and then I have to go and change it in the parent component there so you can give this any name but it's going to
01:01:40
be the same name in the child but that's not the only thing in order for this question to display properly in the child component we not only have to reference it in the HTML but we have to pass it through the JavaScript so I'm going to create a script tag here and a regular exported object and for now I'm
01:02:11
just going to give it the key props which is another object and I'll put the current question which is also an object datatype that I received from the parent so any variables whether it's a data property or a method that I'm passing from app to question in order for it to display in the HTML I have to reference it in props and say hey I'm receiving
01:02:42
this particular named variable from the parent and you reference it the same way you would a data variable so you have your component state which would be local to this component in data so this is local to the app dot view component and then you can also have props which is any variable passed from another component to this component and you use them the exact same way in the HTML so
01:03:14
let's see if this is working p.m. run serve again so it built I know let me check in my browser there we go and it's showing one of my animal questions the zero question I can check this if I go down here into my view dev tools I'm inspecting the question box component and looking at the props I see I get the current question object which
01:03:46
has the question a carnivorous animal eats flesh the same thing we're seeing on the screen and if I go to my app component I can look at my index which is zero so if I edit this and say one then it actually changes the question that I'm passing to the question box component because now it's out the first index instead of at the zero index so if I go back to question box you can see the question has changed so let's set up the navigation between questions this
01:04:18
next button without having to go into the view dev tools to change the index back in my out dot view component after data I'm going to create another object called methods and in here I want a method to increment my index value too so I can navigate through the questions so I'm going to call it next as a function this is basically a shorthand syntax for having a key of next and a value as a function
01:04:53
but I can just write it like this in JavaScript and in here the only thing I want to do right now is take the index which I can refer to as this dot index in my method and increment it by 1 so this dot index plus plus and that will take the current value of this dot index and data and add 1 to it every time the next method is called so I'm also going to want to pass the next method into the
01:05:23
question box so the same way I did with current question I'm going to pass in the next function and then go to question box and receive it here in my next button and just spread this out I'm going to add an act click method and then call the next function on click and of course down here I have to receive that prop so I'll say next which is also
01:05:56
a function so now when I click the next button it should increment the value by 1 by calling the next function in app dot view and then app dot view should pass down the next question in the list so let's see if this works view is still running and let me go to the browser so I have my zero index right now and something's not working correctly it says current question is undefined at
01:06:27
question box so let me go in here and see it's still at index 0 of course because we're getting an error and here I have the next function and current question so everything looks ok in our data and I think we're not quite getting the best message so I'm gonna check in another browser copy this go to Chrome and now I can check in the chrome dev tools and
01:06:59
here it's saying cannot read property question of undefined so let's go to the question box component and see what it's talking about oops cuz look in question box it says cannot read property question of undefined so that means current question is undefined but when we look at the dev tools its defined so that means for a brief moment when this component is
01:07:29
mounting it's still waiting for the data to come from this component and we can see that I'm just gonna add a life cycle hook here and I'm just going to console dot log this dot current question then I'm back in the browser I'm gonna refresh this and it's undefined but in
01:08:01
the dev tools it is defined so that means right when the component mounts it's still undefined and it's a moment later when the questions come back from the server and it goes into the state in this component and then it gets passed to the question box component so an easy thing to do would be not to render the question box component until these questions are defined so wait until we fetch the questions and save them in the
01:08:34
component state until we render this component so I'm going to add a V if directive and I'm going to say V if questions got length so if the array is empty then the length will be zero which is a falsie value so the question box won't render but as soon as the questions come back from the server the question length will not be equal to 0 and so question
01:09:05
dot length will be truthy and question box will render so let's see if this fixes the error refresh let me go to the console and now there's no error of course we're still getting our lock but it fixed the error because now for the brief moment in time question Bacchus is not rendering without the data available to it and now we are able to also navigate between questions just as we
01:09:36
would expect with the next function incrementing the index of course there are still problems because when the index gets to 10 it'll throw an error because that's passed the length of the questions array and we'll fix that in a minute back in the question box component let's add the list of answers here instead of the dummy text so if you remember our data structure had a list of the three incorrect answers and then the correct ones separately so to display all for
01:10:07
answers we just need to put the four answers together so as a temporary solution let's use a computed method so I have an object of computed methods and I'm gonna call it answers so I basically have to take current question from props and the array of incorrect answers and I'm actually going to assign this to a
01:10:37
new array I'm gonna say let answers equal current question incorrect answers and what I'm doing here is making a copy of the array instead of referencing the same array and now I'm going to need to take answers this SURS array and append or push the correct answer on to the end so I take current question dot correct answer and
01:11:11
I push that onto the array and of course this is the array that I want to return so I'll just return that so I should have all four of my answers in this array now and for right now I'll just replace it in here with a v4 so I'm gonna do V 4 equals answer and answers which is going to reference our computed answers and here it's going to complain
01:11:41
because for any V for loop I'm going to need a key attribute so view requires this for accessing these elements in the Dom so I can do a V bind key and usually you want to do something unique here we kind of know all of the answer or each answer is going to be unique so each paragraph tag that is created in this for loop is going to have a unique key which will be equal to the answer
01:12:14
usually if you're doing this in an actual application you'll want to use some kind of unique identifier or view also gives you the option here of getting the index in the array so you could call it index and then use index here as your unique identifier and I guess I'll just leave it like that for now now if we were to look at this right now we would see four empty paragraph tags so I'm gonna put the answer text
01:12:45
inside with double curly braces save that now I'll test it in the browser go here refresh looks like I'm getting an error what error my getting seems like a similar error to before I'm getting current question is not defined Oh so I actually referenced current question incorrectly if you look here I'm referencing current question but that's assuming that it would be an accessible variable actually
01:13:20
because it's a prop I need to access it through this stock current question and I'm gonna have to do this stock current question about correct answer as well so this should fix the problem and actually anytime you want to access a prop or a data variable in another function whether it's a method or computed or anything else you have to do this dot the name of your variable so I'll save that see if that fixed it and yes it is fixed these are just old error so I'll refresh
01:13:52
so it is fixed but we're getting just the numbers of the answer and not the answer text so there's actually another mistake here and it was in how I returned answers so I'm going to pre push answers here push the correct answer onto the array and now I will return answers and that should fix the problem yep and now we're getting the correct looping through our answers and they're all for displaying if we go to the next
01:14:22
next next and it's displaying all their answers now we actually want this to look a bit more like a list and also make it clickable for the users so I'm gonna go to view bootstrap again components bootstrap view and I'm gonna go down to should be a list group here's it here it is and we want to display it like this this will make it easy for a user to hover and click on an element so this is pretty easy I'm just gonna copy
01:14:52
this list group here since this is exactly what I want it to look like go back to my code and I'm going to paste the list group in here these tab them over and I'll get rid of all except one now I want the list group on the outside and I want to loop through and make a bunch of these items I'm gonna put this on another line put this over format it
01:15:22
nice and now I can copy paste the loop v4 loop and also copy this and then put the answer inside instead of the dummy text and that should work let me save that and see how it looks in the browser go here and it works just fine so I don't really like how the buttons and everything are rubbing up against each other and then up against the
01:15:57
answers so if I look in my dev tools I can refer to these with the classlist group or list group item so I'm going to copy this class go back to the application and just add a style tag to the bottom any view component can have a style tag in it and there are different options you can use for styling I'm just going to use default CSS you can also
01:16:30
use sass if you want to I'm also going to denote that these styles are scoped meaning they won't be global Styles that will only affect styling in this component and I'm gonna paste the class that I copied and say that for the list group I want to have a margin it's a margin bottom of 15 pixels save that see
01:17:01
how it looks and there's a little bit of padding now for the buttons I'm gonna put a sideways margin and I'm gonna reference these as VTN from the button class so I'll put margin I'll just make the top and bottom zero and then left and right maybe I'll give it five pixels save that and now it looks a little bit better spaced out so now to make the
01:17:32
buttons clickable let's go back to the question box component and I want to add an act click function here so I click equals a new function I'm going to create called select answer and I'm actually going to pass it the index of the answer that was selected and I'll go down and create this
01:18:00
function under methods an object and selected answer and then I'm just going to log out the index here let me test this in the browser see if it works and it does so I have the correct index of the answer I'm selecting the next thing is to save the select index on the component so I'm
01:18:35
going to create a function here and return an object of our data variables and the first one I'm going to say is selected index and for right now I'll just set it to null and now down here in the selected index method I'm going to say this dot selected index equals index and we can see this in the view dev tools go back to the browser
01:19:13
I'm gonna refresh go to the view dev tools and in question box I can see selected indexes no okay so I tried refreshing and let me click again and again and for some reason the state here isn't updating but if I hit refresh in my view dev tools then the state updates to the correct number and now if I click on this first one here and click
01:19:44
refresh now the State updates to zero so for some reason the view dev tools aren't updating but our function is working correctly there are still a few more steps to do to be able to get our answers working correctly and first of all there's no visual feedback to the user to let them know to first click on an answer or that they've selected an answer so let's first create a hover style and I'm going to go below here
01:20:13
copy this and say list group item hover hover state so when the user hovers over it I want to just change the background color slightly right now the background on the answers is white I believe so let me change it to a shade of gray if ffff is white maybe I'll do a EEE and see how that looks now when you hover over it you can see that it's a clickable item
01:20:47
another thing I should add is changing the cursor to a pointer and now when I hover I can see that I have this little clickable hand unfortunately when I click let me click on Neanderthals and I still have to refresh this it's selecting the index in the data but the user has no feedback here as to which answer they've selected or if the application is even working so let's fix this by adding selected
01:21:21
classes back in the code I'm gonna add two more classes here one is for a selected answer and I'm going to give this background color let's just say blue for right now background color of blue and then a correct answer when the answer is correct I'm going to give it a background color of green and one more
01:21:55
when the answer is incorrect I'll give it a background color of red in order to add these classes into the code we're going to use one of our data variables selected index which should be set to the user selected index when they click on an answer and we need to add a V bind property here and bind and bind a
01:22:26
CSS class to this so I'm going to put class equals and then it's going to be an array we're actually going to add things to this later on but for right now I'm just going to do selected index if it equals index then I'm going to use a ternary and I'm going to say let's give it the class selected selected and
01:22:56
if it's not then we'll give it just an empty string no class save this and then in the browser let me try selecting and it's not quite working when we look at the console if i refresh then it does work unfortunately it's a really dark ugly color so let's just change it to maybe a light blue let me go down
01:23:26
selected could be light blue let's do light green back in the browser no it looks much better and then if you go next of course it's not clearing the answer which is another bug we're gonna have to fix a second bug is that our answers aren't shuffled so we actually know that every fourth answer here is the correct one and then on top of that our submit button doesn't do anything
01:23:59
yet so let's go back to the code and fix these three things starting with the answer shuffling to shuffle the answers for every single time that the question changes I'm going to add something called a watch method here it's just like computed or methods in that it takes an object of functions and in this object I can watch for changes to my props it will run this function when it changes so I'm actually going to give it the same name as my current question
01:24:31
prop and then when the current question changes from the parent it's going to run this function where we will shuffle our answers every time so the first thing I want to do in the function is to set this dot selected index back to null every time the question changes and then I want to shuffle the answers that shuffle answers and shuffle answers is
01:25:03
going to be another method that I create here and I'm going to copy paste this answers array I was creating there and here I'm going to put the the current question dot correct answer so I have them all in an array all four answers now I could do this with a for loop and some randomization but there's
01:25:36
actually a really nice helper library that I can use for this to help me shuffle an array and it's called low - low - is a very popular JavaScript library that's full of useful utilities that might take you a while to write on your own and that are common in many projects like having to shuffle an array so I'm going to go to the low - github and right now we're just going to do NPM Eylau - in the terminal well that's
01:26:13
installing I'm going to go back to the browser and we're going to be using a function called shuffle in the root of the low - github repo you can see that every single utility function in the low - library is listed here as its own file so I can actually go into shuffle j/s and see exactly how it works what algorithm they're using for the shuffle and if I wanted to I could just borrow this one file and any
01:26:50
files that it imports instead of importing the whole lodash library I think it's really nicely laid out in this fashion and it's a very good learning experience if you want to look through some well written algorithms in JavaScript so it should be done installing let me go back to my server and p.m. run serve and now back in my code I'm going to add the lodash library I need another data property where I'm
01:27:23
gonna put shuffled answers this is going to be an array and I'm just gonna call it shuffled answers and here I'll put this dot shuffled answers equals now lodash the convention is to import it with an underscore and then use it instead of calling lodash dot shuffle I would import it as an underscore here
01:27:56
and so I'm going to do that at the top of the script file say import underscore from lodash actually get rid of this mounted function and I need to tell it what array I want shuffled which in this case is the answers array so I do have a typo here instead of saying current question I'm saying correct question I'm just gonna fix that now if I look at the
01:28:26
browser then I'm going to refresh and let's take a look so right now we don't have any shuffle dancers let's see if when we hit next we actually get shuffled answers which you can see bird is the first element of the array at the zero index in the regular answers where we're just appending the correct answer onto the end and then in the shuffled answers bird is the at the second index so we can see shuffling works
01:28:57
unfortunately it only works as we click through the questions also we can check and see that selection works and then it does reset after we click for the next question which is good now how do we get it to shuffle on the first question there are actually two ways we can do this let me go back to the code and the first way is something that you already know we can add a mounted life-cycle hook just like we had before and then we could call this dot
01:29:28
full answers from here and that would work that with shuffle answers on the first component mount and then every time after that when the current question is updated in props it would shuffle the answers which is fine it gets the same functionality but there's also another way that might be a little bit better so I'm just going to show you in these watch functions instead of making them a function you can make it an object and set some options on the
01:30:01
object so I'm just going to comment this out real quick and set it to an object and one of the options we have is to set immediate to true and then we can add a handler oops which is another function and then inside of this handler function we can do the same things we were doing before and it will be called like a regular watch function get rid of this
01:30:34
and now let's see if it does in fact update and shuffle the questions for the first question that is shown back in the browser I'm going to refresh and then check and see if they are shuffled and yes this is great we do have shuffle dancers now so just to reiterate what immediate does is instead of only running this watch function when current question updates it's going to also run it when current question first
01:31:08
gets passed as props and then every subsequent time that it updates it will also run the handler function again here I'm going to update the submit button I'm going to clean it up a little bit first take away this href that we're not going to use and then put it on separate lines because we're going to add a couple more things here for right now if you remember there's the the on directive which I can attach to events I click so
01:31:40
V on click and then I want to run a function that I'm going to create called submit answer and here I'm going to change this directive to use the shortcut and now let's create the function submit answer here down in our methods answer and this will run whenever that button is clicked and the first thing we want to do is store whether or not the answer is correct so
01:32:13
I'm going to create a variable and by default I'm going to set it to false and then if the user got the correct answer I'll set it to true so if this dot selected index equals the correct index meaning they got the correct answer then I'm going to set is correct to true and what this is is correct variable I need to be able to tell the app component
01:32:44
whether or not the user got it correct and also let the app component know that the answer was submitted because in the header we have a counter of the correct answers versus the total answers and this information will have to come from question box through the app component and past as props to the header so let me create a new prop from the app and it's going to be this dot increment and I'm going to pass whether or not the user got the answer correct
01:33:16
so is correct and I'm going to go ahead and add this as a prop here its increment is going to be a function and now from the parent component I need to actually add this function so let me go ahead and pass it down and I have to create the function in methods add the
01:33:46
increment function with the is correct boolean and here I need to keep track of two things the number of total user submissions for answers and also the total number that are correct so first I'm going to check if it's correct so if is correct I'm going to increment a new data variable for the number of correct so up here in data I'll go ahead and add
01:34:19
these so let's say the number of correct answers set to zero and the number of total answers that the user has answered also set to zero to start and down here I can say the number of correct increment that number by one and then the number of total I'll also increment that number by one and I forgot that this here so this dot number correct
01:34:53
increment by one this that total increment by one and I want to do one more thing here and that's passed these two values to the header component to use so I'll add it here I'll use V bind and pass the number of recked and also then um total now in the header to receive these props I'm going
01:35:24
to create the script tag script and export an object with props and I'm going to do props as an array this time just to have both different ways and I'm receiving the number correct answers from the parent as well as the number of total answers and I can put them here with double curly braces so the number
01:35:58
of correct out of the number of total now we changed a lot of things let's look in the browser and see if this works let's see what it's complaining about it seems to be okay right now I'm gonna select an answer click Submit click Next now I wonder why it's not incrementing correct total and
01:36:33
it seems to only be incrementing the number of correct so let's look back in the code and see why the total number is not incrementing so we have sinem total as props that should be fine let's look an app and I'm total is getting past you have none total here and here I'm just doing total so I'm going to put total and that should fix the problem I mean refresh just in case click on an
01:37:06
answer submit and now my num total is incrementing though we shouldn't be able to submit a question more than once because right now there's nothing stopping us from continuously submitting or even submitting before we have selected anything so really we should be disabling the submit button and totally make a selection so let's go ahead and do that and I want it to set as disabled if they have not answered the question
01:37:38
yet so I'm going to do V bind and then the HTML attribute of disabled and I want this to be true if they haven't answered the question yet and false if they have already answered it and then the button will work so I can use one of our data variables selected index because it will be null until they've selected an answer so I'm going to say selected index equals null and let's
01:38:13
look in the browser and see if that works now so it is disabled I can't click on it right now but when I select an answer it gets brighter darker and now when I hover over it you can see the hand and now it selects correctly and if I scroll up it will still be incrementing two out of seven great now let's work on not being able to submit the answer multiple times like we can right now what we are doing here just
01:38:45
checking if the selected index is null only accounts for the case where the user has not answered the question yet so we're going to have to add another check to see if the question has already been answered and if it has then also disabled this so I'm going to add another data variable called just answered and set this equal to false and then up here I'm gonna say and
01:39:18
answered so as long as both of these conditions are met and now I'm going to have to add these to some functions down here in the submit answer function I want to set this dot is or this dot answered equal to true because they've already answered the question if this function is running and then in my watch
01:39:49
handler I also want to reset this dot answered as false for every question I think actually in the button I think I'm actually going to have to do in or here so if it's null I haven't selected an answer at all or if it already has been answered in either one of these cases it should be disabled let me save that and then go to the browser just refresh and then see my button is
01:40:28
disabled it's probably not a very good color for a disabled button oh well and now it's enabled and now I submit and now it's disabled again after I submit and it counted up and I got the incorrect answer now it would be kind of nice to see which one is the correct answer because I know I got an incorrect because of this counter but I don't really know which one of the other three was the correct answer and I can't submit it again so let's change that in the styles jumping back into the code let's store
01:41:01
the correct answer I scroll down to my data I'm going to add another variable called correct index and I'll set that equal to null initially and now when I shuffle my answers meaning when I get a new question I'm going to store which one of the answers is correct I'll go down to my shuffle answers function and I'll say this dot correct index equals
01:41:34
this dot shuffled shuffled answers inside the shuffled answers array I want to get the index of the correct answer after its shuffled so I'm going to use the JavaScript property index of on the array and then I'm going to say it's the index of whatever the correct answer is so I already have the correct answer stored in this dot current question dot
01:42:05
correct answer so now this should keep the correct answer so we still know it even though all the answers are shuffled together so let's see if this is working go to the browser pretty fresh now look at my question box and I have hmm well that's interesting I must have made a mistake in typing this out let me go and check the code and see what I did I actually misspelled shuffled answers I
01:42:42
left off the S so now I'm gonna save this go back to the browser again and it shows the correct index let me go to the next question and the correct index changes per question unfortunately as a user how do I know if what I selected was correct there's no way for me to know it just moves on to the next question so let's add some functionality
01:43:13
and styling so the user can see feedback that the answer is correct or not and in doing this we'll need to make the submit button work as well if you remember a while back we made these different CSS classes selected correct and incorrect and so far we've only used the first one so let's use the other two we show the correct answer as green after they hit submit and if they selected the incorrect answer then that's going to turn from light blue to red so we're
01:43:44
actually going to make a dynamic class and here I'm going to put this on a separate line because I'm going to be adding some stuff just for the time being here we actually only want this selected class to appear if the question is not yet answered so I'm going to add a not answered here and selected index and just for a second I'm going to be nesting turnery statements here and then I'll clean it up after so right now we
01:44:16
have the case where it's not answered and they've selected a choice so what about if that case is not correct so here I'm going to add a case if it's answered and the correct index equals index in that case they got it correct we want to show it as correct and I
01:44:49
believe that's the name of our class here yeah correct and otherwise we can show it as nothing so let me save that and see how it's working so far yep so that's the correct answer and now it shows the correct answer there so there's gonna be another case that we have to add here after here so I'm gonna
01:45:24
copy this actually and if it's not equal to index I'm gonna say we're going to use the incorrect class otherwise note class so if it's answered and they didn't get the correct answer then I want it to turn red so let's see if that works obviously it didn't work that well because every incorrect answer is turning red and I just want the user selected one to turn red so back in the
01:45:58
code I'm going to have to add one more check into this chain and that will be if selected index equals index and this is getting kind of long and back in the browser I mean refresh there and now it correctly shows of course this logic that I wrote is kind of out of hand and it's definitely messy to do all of
01:46:30
this inside of a class just to clean this up we're going to move all of all of these nested Turner ease into a method and we'll call that method answer class and we'll pass it the index each list group item that's created so each answer is going to call this method in order to see what class it's going to
01:47:00
have so I'll go down to methods and add this one onto the end answer class it's going to be passed the index of the answer and then just for reference these are all the nested Turner ease I had up there I'm gonna copy the first one and first I need to create a variable called answer class and set that equal to an empty string I have an if statement so
01:47:34
if it's not answered but they've selected an answer then I'm going to set answer class equal to selected and I'll just change some else ifs here and if it's answered and they got the or the answer is the correct answer then the class for that particular
01:48:04
answer is going to be correct and then a final case is if the user answered the question but they got it incorrect and we want to make that read with the incorrect class so it would be answer class equals incorrect and then down here I'm gonna return answer class let
01:48:39
me clean this up and let's see if that still works yes so the answered is not defined and that's because again I forgot to put this dot answered so remember in the template you can use any of these variables but if you're referencing them in the JavaScript you have to reference them as this dot so this dot correct answer this dot answered and this style selected index
01:49:12
and this dot correct index so this is kind of long I'm going to put this on a few lines and that should work so let me try it in the browser again seems to be working it's selected correctly now I can submit and I got it wrong so it's red and green try one more question I submit yep it works perfectly our counter is still working this is the whole quiz application the github code will be linked below if you want to take
01:49:48
a look and you can see that there are different branches so you could look at different parts of the tutorial in different stages if you wanted to now we're going to build an app that's slightly more complicated to demonstrate how view routing and view X which is view state management system work it's going to be a basic four screen application it's theme is getting cats and dogs to be adopted and we're going to be performing basic crud operations to get used to state management now
01:50:23
there's a home screen two screens one for cats and one for dogs and then you can click on any animal name either cat or dog and it will load a screen just for that animal so here in the terminal I'm going to create another view application using view create and I'm going to call it adopt pets now if you remember last time we use the default boilerplate this time we're going to manually select features to manually
01:50:54
select you can go up and down with the arrow keys and press spacebar such as here I want to select router so I press spacebar I also want view X if I wanted to use SAS or something I would select this one and then I think I'm gonna leave testing out of this particular application so that's all I want I'm gonna hit enter and then it asks me a few other questions history mode for router is literally a one-line change in the router and I'm going to show you how that works later for right now I'm just
01:51:26
gonna put yes I'm gonna pick SAS since it's the most popular CSS preprocessor and I want to show you how I include it my applications for this I'm just gonna put standard config although prettier and airbnb have some nice features as well either way all of these are just templates and starting points so you can always modify any rules that any of these set for you I'm just gonna have it run linting every time I save a file and this is a personal preference of mine I like to have my configuration in their
01:51:57
own files such as my unit testing config Babel config or my es lint file by itself instead of cluttering up the package.json that can get pretty unwieldy now if I want to save it as a preset for future projects I can click I can type Y and it's going to ask me to give it a name I'm just gonna type no here and then show you the one I already have and now it takes a few minutes to build the project great it's done installing
01:52:30
I'm going to go into the adopt pets directory and open this in vs code this is very similar to the project last time still have the index.html in public a few differences here are that in the main j/s instead of only rendering the app we're setting our store for view X as well as our view router configuration in our view options another difference
01:53:01
is you'll notice that here we have a views directory and a components directory now if you look in the router you'll notice that home and about which are the two routes are both views so these are the pages of your applications which are connected to the router and components are imported into the views or into each other so if I look in home I can see it's importing the hello world
01:53:32
component hello world up view and it's displaying it to the Dom the idea is that components are reusable pieces and each page stands alone as a distinct view in your application now if I go back to the router there's a lot of things you can do such as lazy loading or even using multiple components here but I'm going to keep it simple for now so I'm gonna take this out of here and import and now I can set component to
01:54:06
just about and get rid of all these comments and now it's and it renders exactly the same it's just a bit easier to read right now now the store I'm just gonna give a quick overview and I'll go in deeper you're basically creating a new view X store which is a global object so any functions or variables data anything that you want to use maybe in multiple parts of your application you can store
01:54:37
them all here and then import them into whatever component you want and it's like a global object for your application the first thing I want to do in this app is create the four pages and link them together if I look in views I have about at home I'm gonna go ahead and leave the home component and delete the about one and then create one called Kats top view dogs that view
01:55:13
and the other one I'm just going to call pet dot view and I'll put a boilerplate template here and I'll do the same thing for dogs put just the template here and one for the pet page and now I'm going
01:55:44
to hook these up to the router now I've defined all four routes that I'm going to use in this application I'm going to update my app file to link to all four of those pages instead of just home and about duplicate those and now put cats dogs and the pet page which eventually is going to be linked through these two pages but I'll just leave it for now dogs and cats and let's see how that
01:56:46
looks okay it has all of the links here you can go to the different pages I'm just gonna add this pipe in between copy this there looks much better now let me get rid of all this extra stuff on that page which is in the home component importing hello world and using this image I'm just going to get rid of both of these and just say home get rid of this and
01:57:26
this and now I'll delete the hello world component perfect now just like before I want to import view bootstrap to help do the styling for me and lay out the pages I'm gonna go to the browser view bootstrap get started and install it
01:58:00
with NPM so stop my server and NPM I bootstrap view now back in my browser I can copy the import of view use and I'll put it in my main.js file I'll put it up here with my other library imports and since I don't have a section for views I'll put it right there now I
01:58:39
need to import the CSS as well so I'll go and grab these links and put them here and that's it now that I'm importing view bootstrap I'm going to use some of their table components to display the tables of cats and dogs so if I scroll down here see they have table and this table looks fine to me so
01:59:11
I'm going to copy this be table and save it and go back to my code and let me close some of these now let me start with cats and here I'm going to add that table component and now of course I need the data so I'll add a script tag and close it and export default this object data function and return an object and
01:59:44
now back in the browser you can see I need an array of objects which I already have in another file and I'm just going to copy paste that into my application so I'll create another folder in source and I'm just going to call it data and in data I'm gonna make two files one file cats dot J s and the other one will be dogs dot J s and I'm gonna copy and
02:00:17
paste data that I already have here here are my dogs this is an array of dogs so I'll do export default this array and I have some different information and metadata about the dogs and make close this one and now I'll add my cats which is also a very similar array I'm gonna add them here
02:00:50
and now back in my cat's top view I'm going to import cats from pet data / cats now this @ symbol is a shortcut that view CLI sets up for you and it's a reference to the source directory so that way you don't have to do things like dot dot slash dot dot slash dot and
02:01:23
whatnot so I'm just going to use the shortcut at and now I'm going to return cats here so this is the same if you don't know the shortcut this is the same as setting a cat's value equal to this cats array that we're importing but the shorthand is just to do it like this since they both have the same name so now for items I'm going to say cats here and I'll see how that looks in the
02:01:55
browser back in Firefox if I go to adopt pets and refresh I must have stopped my server let me look back at item and yes I did so let me run npm run serve again great my browser all right it's working and now I have a cats table showing all of my cats I'm just going to clean this up a little bit so it doesn't go all the way to the
02:02:31
edges of the page here and I'm going to add a be container in my app top view so for this router link I'm going to wrap it in B container which is another bootstrap component provided by view bootstrap and I'll go back to the browser refresh and that looks much better as far as the width I also need a page title so let me create that real quick back in cats I'm going
02:03:04
to have an h1 here and say this is just cats for adoption alright that's good not too fancy but looks fine now I'm going to copy paste this and do the same thing for the dog's tab and I'll go back here go to dogs I'm
02:03:31
gonna copy paste this table and the script tag and then I just need to change it to dogs here's well and here great so those two pages are looking good just to finish up the home page I'm going to change this to an h1 as well and I'm going to say
02:04:11
adopt new best friend h1 so that's all of the nitty-gritty out of the way now if I go back to my browser you can see that I have these three pages but this page is supposed to be that of an individual cat or dog kind of like seeing his individual profile so if I go to cats for example then the pet page should be something like cat slash one for the ID of that cat so let's learn
02:04:47
how to do this through the view router view router has something called dynamic route matching what it does instead of hard-coding the whole route you actually have a dynamic route variable as part of the route it's preceded by a colon and then you can call the variable whatever you'd like and then you can access this variable when you go to that route in the component associated with the route on the route params object so let's see
02:05:18
what this would look like in our pet component first I'm going to update the router and say here under pets I'm going to change it to be plural pets and slash ID for the pet ID and I'm going to leave these as they are for right now now let me get rid of the link in the app dot view file to pets let me just get rid of that and now we need our table components to have links to the pets
02:05:50
page for every item so we'll have to update this table since right now it's kind of a black box and we're passing in this array of cats to a third-party bootstrap component so let's go to the bootstrap Docs and see how we can turn each cat in the table into a to that page I'll go to the browser and I'm still under the bootstrap component tables this whole page is pretty big so I've skipped down to this format or call back and basically what it allows you to
02:06:20
do is pass in a template with a dynamic href so let's copy this and go back to the code I'm gonna expand this close it here and put this inside now I want to mention something about slots because you're probably going to see this a lot in view especially if you are using third-party libraries like via bootstrap or if you are creating your own
02:06:52
components for someone else to use now in bootstraps be table component it's going to look something like my formatter doesn't like this very much so it's gonna look like template and then have something exactly like what we have with maybe a div inside and it's going to have a bunch of other tags and it will have this similar slot so bootstrap is basically telling the
02:07:25
component where to put things that we pass in to the this.b table so it has different slots inside and if it has multiple slots which in this case it does it will say name equals name which will be dynamic because we have lots of different columns that could vary in the table so bootstrap will have a slot for each of our columns and that's how we can pass it in here if you want to know
02:07:56
more about slots they're pretty easy and they're described really well in the view documentation and here I'm just gonna replace this with slash pets slash variable data dot value and I'm going to change this to a router link not using a tag to router link and I've got a link here do link you can use an a tag I think it's a little better and more
02:08:29
consistent to use a router link so let me go to the browser and refresh and now I have links for all of these now I don't really want it to have the pet's name I want the ID so let me go back and change it and instead of data dot value which will give me the name of the pet I'm gonna do data dot index which will give me the index of the row in the array so let me go back to the browser and try this and now if I let me go home
02:09:02
now if I go and hover over it I can see the link gives me the index and if I go here you can see in the URL I've pet slash is zero which is the ID of the pet in the so now I want to populate this page with the details on the individual pet so what I could do is take these pets arrays and import them into my pet component and then get the index off of the router variable and just look in the
02:09:33
array in this component but I'm actually going to put all of the pets dogs and cats in state and then pull the pet I want from State so let me go to the store and this is a very small project so I don't need to do this but I just want to show you how I generally set this up I make a new folder called store and in store I make a separate file for everything so I'll have a file for state
02:10:03
J s and one for mutations J s and then one for actions jeaious and now I'll make an index file to tie these together index J s and I'm going to take what's in store right now take all of this copy it put it in the index file and now I'm going to import the other three files so
02:10:34
import state from state report mutations from mutations import actions from actions and now I can use the shortcut here and here
02:11:07
oops this object and get rid of that and now of course I need these to be actual objects in each file I'll just for some of these export a blank object for now the same thing in mutations save this save this and now in state I'll have a blank object but I'm also going to be importing the cat-and-dog data so I'm going to import
02:11:41
cats from puppet directory data slash cats and I'll do the same thing for dogs oops dogs and dogs and now on state now this object is the default state of my application so it's the data that I'm going to be able to pull into any component that I want so for right now I will have these separate I'm going to do
02:12:12
cats and dogs as separate arrays on my state and now what I can do with this is go into my cats top view and instead of importing cats from here I'm actually going to import something from view X called map state from view X and down here I'm going to use a computed object
02:12:47
computed and the syntax for map state is to use a spread operator and call the function and pass it an array of the items on state you would like to be able to access from this component so here I want to access cats from state so I won't actually need this in my data anymore and I'm gonna get rid of it so now I can get it directly from my view X store
02:13:20
I'll get this array so let me go to the browser make sure that's working go home refresh now let me go to cats and it's not working so I must have an error let me see what error I have none here let me go to the terminal now that looks good so let's check the dev tools and see if we have a problem with our data there and in my view dev tools I can see cats is undefined so let me see why it's undefined if I go
02:13:49
to my vias code it seems like I am mapping the state correctly from UX so let me look and see if it's in the view X dev tools may be u X and in my base state I don't have anything in my base state so let me see why nothing is in my state if I go back to this code so I'm pulling in the store from here so I think the only thing I'll have to do
02:14:21
here is just delete this old file because now it should look at the relative path store which is now a directory and since I'm not specifying a file it's going to look for the index.js file and I'm exporting as default the store from there so let me go back to the browser and refresh great now it's working and I'm getting the appropriate pets so now I'm going to do the same
02:14:52
thing for dogs so I'm gonna take this actually the whole computed here and go to dogs and I'm going to add the computed object here and I also need map state to connect the view X state from the store to this component and I'm going to map dogs here and I'll get rid of dogs in data perfect so now how do I
02:15:26
figure out whether it's a dog or a cat in the pet component I could set this up a few different ways but for right now I'm just going to put slash cats here I'm going to turn this into another variable and because this isn't in my dog's component I'm going to copy all of this and come back to dogs instead of the end here I think I missed the template oh yeah
02:15:56
that's actually important so I'll come back do this and I'm gonna close the table here and I just need to change this to dogs now in my router I'm going to have to change this to store the species and then the ID let me just make sure that's working back in the browser now if I click on one of these it takes
02:16:29
me to the species and then the ID and now I can access these from my component so back in my pet component I'm going to say this dot route actually because I'm in the template I don't need this so I'll just say route dot and believe it - params dot species and then duplicate
02:17:03
this row and dot ID let me see if that works so back in Firefox and it does work as the species and the ID now quick way for me to get to the right cat in this component is to pull in the cats and dogs from state because this component is its own view and it's not connected to cats or dogs so I'm going to copy the script tag here and then modify it I have map state which I want and I'm
02:17:34
going to add dogs here so I can listen to cats and dogs from here and I just want to mention real quick that you could do this same thing by saying cats adding as a method here and then returning something like the stat store dot state cats and this is actually the same thing as doing map state here but you're never gonna see this in an application this is pretty
02:18:06
much the standard syntax it's shorthand and it's easier to do because sometimes you have a lot of elements on state and it's much easier to just use the map state method and now I have access to these in my Dom so what I want to do is find out if it's a cat or a dog and then display the information here so I'm going to make a method for this real quick methods object I'm going to call
02:18:36
it pet pet and inside of pet I'm going to check for first this species so I'm gonna say that animals equals actually I need this here this dot route to params dot species and now this will either return cats or dogs and so I want to
02:19:09
access it on my this object so I'm actually going to pass it in as a variable if this is confusing to you then it's the exact same thing as accessing these arrays off of state so I could do this cat or this dogs but I can also use the bracket syntax and pass in a variable here so I could pass in this dot cats which is exactly what I'm doing right here get rid of that and now I have my animals here and on my animals I
02:19:42
want to see which animal I want to display I'm just using an index right now so it's easy if I was using an ID then I would have to search through the array and find the animal with the correct ID so for right now I suppose I'll just say animal and then pass the index of the animal which will be route params ID so I can do this dot route de params
02:20:13
ID here and that should get the correct animal and now I'm going to return that animal and I should be able to use it in my Dom so let me see if this works and instead of all of this I'm just going to have animal dot name go back to my browser see if I don't have any errors but I do oh yes property or method animal is not defined of course because
02:20:44
I called it the wrong thing so the method is called pet so I actually have to get rid of animal here and I'm calling it pet and then I'm returning animal from here so this should return the correct animals name and let me check it back out in the browser and great so now if I click on let's say KitKat it shows up with the correct name of course this is a little bit messy and I don't want to be calling the method every single time I want a property off of
02:21:18
this animal so what I can do is in data I can put animal and set it equal to an empty object and then here instead of methods what I could do is put a lifecycle method here so I can say for example when the component is mounted get rid of this and now I can set this dot animal equal to animal which will
02:21:49
set animal on my data object and then up here I will be able to access animal dot name and let me wrap animal name in an h1 let me close my h1 and I'm gonna add the animals age here as well so animal died H close the P tag and I think I have a breed property so let me just add
02:22:20
that one real quick - so animal dot breed now I'll go back to the browser also so these are old errors I can just ignore them now I have the name of my pet the age in years and then the breed and this works if I have dogs as well now I could probably put something to denote whether it's a cat or a dog here
02:22:50
so I think I should take this species and I'm going to add that in here and I'll put it inside parentheses and then I also want a label for the animals age so here's old and for breed I'm going to put this I should have this here too for age I can put here and that should look a
02:23:24
lot nicer and now when I go here I can see I have labels on these and I can now see if it's a cat or a dog great so another thing we probably want to do is be able to edit these animals to add crud operations and that will lead into how to use actions and mutations in the store so let's jump back into view X let's start by adding the functionality to be able to add a pet to do this we're going to have to
02:23:56
append the new pet to the array in store to one of the arrays now the pattern that you'll generally see for doing this is definitely not updating state directly because that's what mutations are for mutations are there to update State for you and generally speaking you will call an action that calls a mutation which update State and a lot of the time the actions that you call will be where you're also making API calls because they're asynchronous so we're
02:24:29
just going to use that pattern of using actions that call mutations that update state so in actions I'm going to add an add pet method and view gives me a context object here and then I can use an argument when I call this function and I'm just gonna call that pet for right now make this an arrow function and with context here it has a commit
02:25:00
method on it so I can use commit and now this will call a mutation for me so I'm going to need to create a new mutation and I'm going to call it append pet and I'm going to append the pet with my new pet object that's going to be passed into this function I want to make a note here that this is generally not how you will see this being used because context you own need the commit message off of it so you
02:25:32
can actually pull that directly off the object here and this is generally how you will see commit being used and remember this object comes from UX and this pet is the custom parameter that we're going to be passing into the function now I'm going to copy this name append pet and go into mutations and I'm going to add a mutation called append
02:26:02
pet here again we have two parameters so the first that view X gives us is state so we have the application state and then the second is whatever payload we're passing into this function so that would be pet here and I'm gonna make this an arrow function again and from here we can mutate or update state so I'm going to say so state dot whatever species which is an array so I can
02:26:34
actually push the new pet onto that array to do this of course I'm going to have to pass species into this with pet so here I'm going to change this so that I'm passing in an object with pet and also the species of the pet so for shorthand and because I'm just passing this straight through I'm just going to call it my payload which will have payload pet and payload species and I
02:27:07
can pass this payload directly into my append pet mutation and from here I can D structure this and say species and pet and state species which will be cat or dog and I'll push the new pet onto that and that should append to either our cats or dogs arrays so I'm
02:27:41
going to do this for cats and dogs at the same time so I'm going to go to home and add a button here with a bootstrap class of BTN and I think BTN primary to give it some color I'm going to say add new pet and this should toggle and add new pet form and now in my JavaScript I'm gonna add a methods object and say
02:28:13
toggle pet form and this dot pet form equals the opposite of this dot pet form and of course this is going to be a boolean so I also need to add a data method and return an object of my data variables and one of them of course will be pet form maybe to be more explicit I should say show pet form so it's obvious that it's a boolean and to start off
02:28:48
with I don't want to show this pet form so I'm going to say it's false and then every time that this method is called it will toggle the form from showing so now we actually need the form and for that I'm going to copy a view bootstrap form and I'm just going to take this most basic form at the top and then modify it so I'll come down here and copy everything in B form
02:29:22
go up B form and now back to the code going to add that form here that looks good and I have to of course update all of these functions because it's not going to run right now so get rid of at reset which I'm not going to use now show pet form so it will show this pet form if this variable is true so this button will toggle it and I'm going to
02:29:53
make a handle submit function for when the user submits this form which will eventually call our action right here I'll add the handle submit function and for right now it's not going to do anything so let me just fix the rest of my form real quick we want the pets name first and foremost we don't need an email address for the pet so I'll get rid of that one and now this example input group I'm gonna say
02:30:24
pet's name and for the drop-down I'm going to say species and for options it will just be an array of cats and dogs to choose from and that should give me a good drop-down menu I'll add one more form group here copy this one and overwrite the check boxes and I'll say
02:30:57
pets age enter age here and the type will be a number now here of course all of these V models I need to update so I'm going to make a new data variable here I'm going to call it form data and it's going to be an object that's going to model all of my different form inputs so I'm going to have formed added name
02:31:29
which will start as an empty string and I'll just give age a default of right now and species I'm gonna say is no and let me update these here so form dot age farm dot species and name is fine so I also need to update this to form
02:31:59
data instead of just form form data and one more form data so our form should be functional all the way until submit right now let me just try it in the browser I have the add new pet button and it's not toggling the form so let's see in the view J s dev tools in app in the home component show pet form doesn't switch to true ever so let me say true
02:32:32
here and it does show the pet form now I know where the error is happening I go back to my code I can see that this toggle pet form is never being called because I forgot to add it to the button so I'm just going to do and add click here it's a toggle pet form that should work back in the browser refresh and now it toggles on and off great let's hook
02:33:03
up the submit button in the JavaScript here I'm going to import another view X helper called map actions and this works in the same way as map state to do this we need to add map actions to methods now the reason why we add the actions to the methods and the state to compute it is that we are
02:33:38
watching for changes to state and we're not watching for changes to these static methods they're just functions for us to call so that we can get state updated so now I'm going to pass in an array and my action was called add pet so I'm mapping that to my methods and now I'm going to call it from handle submit and I can do that by just saying this dot add pet and
02:34:10
then passing it the payload so the payload is an object that I'm going to create here it's a Const payload equals this object and the payload should have the species and then it will have a pet object with things like the name and age now to get this information I'm going to pull it off of data here so the form data object
02:34:42
and I can do that by using this syntax I'm gonna pull species age and name off of this dot form data and I'll put this in the wrong spot so take this outside of that object and now here I should be getting all of my right information passing it as an object with species and pet as the payload and then this will go
02:35:14
into the actions here as my custom payload that I'm passing through to mutation and the mutation will have species and pet pulled off payload so I can update state cats or state dogs and push the new pet let me see if this is working in the browser I'll refresh this add pet we add Bosco and he's a cat
02:35:49
submit okay so if you notice the page refresh here it was pretty quick but it's not actually going to submit the form correctly because of that refresh it's handling it in the default way when it's supposed to be submitting a form to a server but of course that's not the functionality that we want so I'm going to come back here go to home and now for our submit handler I'm just going to add dot prevent and if you remember this
02:36:20
modifier is just like calling event dot prevent default just like you would in a regular function submit handler but this is a shortcut that view has so I'm going to come back to the browser and now if I add a new pet cat the age is 22 and I'm gonna submit this and I think it's submitted correctly but of course we're not clearing out the form after so there's no feedback whether or not is
02:36:52
submitted so let's go to cats we see a cat is appended to the table awesome now I just want to clean it up a bit and clear out the form when I'm done I'm gonna see no it's clear now but I wanted to clear right after I submit to give some user feedback so if I come down here I'm going to add something to reset the form after submit so I'm gonna say that this dot form data equals an
02:37:26
object and I'm gonna reset it to exactly what it was before these okay now let me try to submit another pet this time I'm going to submit a dog 12 submit and now it's resetting the form after it's submitted and let me go to dogs here and it correctly added the dog of course there's a lot of other things we could add but that's basically how view X
02:37:58
works is that you'll call an action from a component and actions are asynchronous and then from the action whenever you're done doing what you want to do with the action you call a mutation and then the mutation update state and then whatever components are listening to state because you're mapping the state to a computed function those components will update in the Dom where it's needed now I want to show you real quick how getters work there is actually another
02:38:28
object that goes into the store and it's called getters so getters are like computed properties but for your view X store what does that mean perhaps you want to pull state into a component but you want to modify what the component receives while you're pulling it so it won't actually update state but it will get back something that you want out of state for example we could count how
02:38:59
many animals we have in our arrays in a getter and then call that getter it from everywhere we want to get the number of animals so let's just create that real quick I need to first create a getters object and a getters file and it's the same as the other view X object
02:39:30
so I'm gonna export default in object here and I'm going to call it animals count which is a function and here I'm going to have access to the state and I can do whatever I want with the state before I return it to a component another arrow function and if I want to get the total count of both cats and dogs I could say something like state
02:39:57
dot cats dot length plus state dogs dot length and now to use these getters I need to put it in one of my components so I'm actually going to put this in the home component and I'm going to put it just above the button so I'm going to say animals count here but of course I need to map this so there's another
02:40:32
method called map getters and I need this inside the computed because we're watching for changes on this so I'll put map getters here and this is using the spread operator as well so that's the method with an array the same format and that will be animals count let me make sure I got that right and almost count animals count perfect let's see if that works in the browser
02:41:03
if I go home and I see I have eight which is exactly how many animals I have because I have four cats and four dogs but of course pulling this from a getter didn't update State at all it's just modifying how state is seen by a component so I can run whatever function I want now one common thing that you'll be using getters for is for filtering so I can say something like get all cats now
02:41:35
to do this I'm going to need to create another I'm going to need to create another array here and this time I'm gonna call it pets so instead of cats and dogs in separate arrays I'm going to give it one array cats and dogs if you haven't seen this syntax before it's basically so that the array is flat because if I just
02:42:08
put cats and dogs without the three dots behind each it would come out being all of the cats in one array and then all of the dogs in another nested array so this is an easy and nice way to make all of the pets together in one array so now that all of the pets are together here I'm going to need to add what species they are inside the data to differentiate between the two so I'm going to add species is cat now I'm
02:42:41
going to copy this and just paste it in all of these yeah one extra comma and I would put this in dogs too but just to show the getter example I'm going to say get all cats will be returned state dot pets which will have both cats and dogs in it and then dot filter the filter method takes a function which will give us each
02:43:17
pet one at a time and allow us to return just the pets we want in an array so I'm only going to include the pets in the array where pet excuse me pet dot species equals cat and now I should be able to use this get all cats getter well once I add state from my component and I'm going to do that here so I'm
02:43:48
going to say add another variable get all cats and I don't want to print out all of those objects so I'm just going to put lengths to see how many cats is returned and of course I need to add that inside my getters get all cats and now I should be able to call this from the Dom and check how many cats are returned versus the total number of pets back in the browser
02:44:20
I see it's getting the correct number of cats versus all pets in case you can't see there are four cats and eight total pets that's basically how getters work it's used a lot for filtering or making changes to what's going to be rendered on the Dom you can do a lot of different things with getters you could also pass in other getters so here I could actually call another getter inside this
02:44:51
getter because view X gives me that as a second argument this whole system is pretty simple once you've practiced it a little bit I want to show another thing that I think would be helpful in a production application or as building your personal projects that is setting up sass inside of a project and this is how I generally do it in view so I add a folder inside of source slash assets called sass and then I have an
02:45:24
index dot sass file and I make a couple folders inside of my sass directory so I have my components and my libraries and my global Styles which I usually call base and then I import all of these files into my index so I'll import first libraries and then base and then I'll
02:45:56
import components here so inside of the libraries folder I might have mix ins or material design or whatever other sass files I want to import here I can also import CSS files I just rename them dot s CSS because any valid CSS can also be used inside of es CSS files which is a type of sass file I just prefer to use indented syntax without curly braces or semicolons and
02:46:28
there are some extra shortcuts that you get with the indented syntax that I like so after the libraries the base files I'll generally have something called variables that sass and now this underscore is just a convention in sass to mean that this file is imported into another file and not compiled as an individual file so I have a variables file and here I might do something like
02:47:00
set my fonts as a variable so I could set let's say main font and set that equal to I'm not sure how medica if that's right or whatever a Google font that I've imported or any other font and then sans-serif and do colors and padding and spacing I'm just gonna do maybe a blue color here which
02:47:31
could be zero zero zero zero three four and then you get the idea you can put pretty much anything you want to be able to use in other parts of your application and then you can just change it in one place and this also makes it easy if you're doing different themes or letting a user choose their theme in their application you just save all the different themes here and then attach them to a class and toggle that class dynamically from the JavaScript inside your view components so now that I have
02:48:08
some variables here I can import this into my main sass file and within at import I'll say base slash variables and I don't need the underscore or the dot sass on the end it's going to look for either dot sass or dot s CSS files and I think this makes the file look really clean it's easy to look through a whole list of these now in the components let me just pull up one component here let's
02:48:41
say a view and my home view and it starts out with the class home but generally I don't think this is descriptive enough so I usually call things like home view container or something like that in my project and this is a wrapper class so that I can contain my nested classes and they don't affect other parts of the application because my global styles will all be in base but each component that I make will also have its own styles so I'm going to
02:49:14
create a new style file for the home component and then I put this wrapper class and then any other classes that I want to affect the home component I'll put nested inside of here just so you can see the nesting I'll put four spaces instead of two which is generally what I use whenever I'm doing something like python or SAS using indented syntax because it makes the indentation easier to see so now I'm just gonna say color
02:49:44
and use my color variable that I'm also importing into my index file so now in components I will at import base slash home and now I have styles that are specific only to the home component so how do we get these styles to apply to the components you have to import them into the main J's file so right below where I have these bootstrap files
02:50:16
imported I'm also going to import from the assets folder sass and index dot sass and now that should apply all of my sass files to my project because if you remember when we created this project from the view CLI we chose sass as the preprocessor so the vo CLI set up all of the sass processing for us and being able to compile it to CSS and things
02:50:49
like that which makes it really easy to use sass inside of projects so it's complaining about this at import statement so let me add components here and now it's working fine although the text is not turning blue let me see why that is if I go to inspect element it is actually blue but it's just so hard to tell because it's not a very bright
02:51:19
color so let me change that to a brighter color if I go into the variables and I'm just going to change this to any color not necessarily blue just so it shows up I have no idea what color this is okay purple and it doesn't affect any other page here because I am using a namespace in sass so it only affects anything inside of this class which is specific to the div wrapper around home
02:51:50
dot view so hopefully that makes sense I do make usually one of these components for every single of my component files and any global Styles I'll put inside various styles in the base directory so that's enough about sass I just wanted to show you how I usually set up a sass project this code will all be online if you want to see it I want to change one more thing that feels a little bit dirty about this project and that is to pull
02:52:21
this table out into its own component in my components I'm just going to create a new file called pet table dot view and I'm going to use this as a table inside both cats and dogs so to start this I'm going to just steal this template put it here and to make it unique for each one we're going to need to pass in some props to this component from both our
02:52:52
cats and dogs views so I need to have props on my default object I'm gonna make this an object and say first of all I think we're going to need a species which will be a string and then here I can replace this with species it's gonna be a lower case and here I'll replace this with pets because we'll pass either
02:53:25
cats or dogs as pets and pets will be in array and then here I also want to use species to dynamically pass that and I think that's it really we just have to import pets table let's import it into cats fur so I'll import pets or pet table from at
02:54:00
components slash pet table dot view and I need to set it as a component I'm gonna use in my Dom here components pet table not sure if I mentioned this previously in the video but using pet table as a component here I can do this in two different ways I'm gonna get rid of this and I can use it capitalized or view gives me another default way to do
02:54:35
it which is kabob case by default to make it more HTML like I could do that generally the recommended way that I've heard from members of the core team and others and also from using it myself is to just keep it capitalized and that lets you see the difference between the custom components that you create and the other HTML tags like div so I'm going to be passing in the species here and I know the species is cats so I
02:55:07
don't have to do anything else to that and I'm also calling for the pets or the cats which I need to pass in and I have that array here mapped through computed so I'm going to pass that in using V bind as pets pass in the cats array of course this is kind of confusing because these have the same name but this one is an array because we're using V bind so
02:55:39
view is looking for a variable so it's actually pulling this variable cats array off of computed and sending it in as pets now species we're not using V bind here so it's just static so it's the string cats and let's see how this works if we go to the browser and go to cats it's still working the same way so I'm going to copy this for dogs go
02:56:09
here into the dogs component and get rid of all this table stuff here except we're going to be passing dogs in for both of these and then we need to pull in the pet table component from here and also add that component so that we can use it in the DOM and I'm going to add it here and then it should work still
02:56:39
for both cats and dogs refresh and it works for dogs just as well and we can still see that we have the correct number of both being pulled in so that's all for this view tutorial if you're interested in going further with you let me know and I might make a more advanced intro to view in the future here are the resources I think are most helpful for getting into view first there's the state of UJS which is a yearly report put out by Evan you who's the creator of
02:57:13
you he gives lots of great talks about how the project and library are evolving every year and you can find those for free on YouTube another resource I highly recommend is somebody who's the senior view developer called the jerod will Kurt he live streams various tutorials mostly about view every Thursday night at 7 p.m. Eastern Time in the USA he's a really great teacher so I highly recommend jumping into some of those chats and asking him questions then there's one of my favorite people
02:57:45
on the view Jas core team Sarah Dresner now I didn't cover animations in this tutorial but she's actually the best person to talk about those types of things UJS has a lot of great built in animation features I'm going to link a video of a talk she gave on view animations that I think is really good one last thing I recommend for getting into view is checking out the views on view podcast you can find it on dev chat TV or on overcast or any of
02:58:18
your other favorite podcasting applications thanks so much for watching this whole tutorial I know it's kind of long but I hope you got something out of it if you have any questions or feedback from me you can find me on Twitter at Gwen underscore Faraday or shoot me an email at Gwen Faraday at p.m. Emmy I also have a youtube channel called coding with Gwen that I'm going to be starting back up here soon and this is kind of a kick off video for that so if
02:58:50
you are interested in more of these types of videos you can check me out there thanks

DOWNLOAD SUBTITLES: