.NET 8 LIVE Coding - Building Blazor Movie

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] what [Music] [Music] [Music] [Music] accepted [Music] hello everybody Welcome to the tech capital of the world we're here in coding Central today at 2m Eastern Kevin Jacob how y'all doing hey doing great ready to code yes always we have announced this say Kevin's doing all the coding we're getting ready to get off so yeah just leave me here this will be the shortest stream ever yeah I've got my coding snacks so you got a cliff bar in case I get hungry it's important to coding nice so what do we building what are we making what are we doing we're gonna build Blazer movie now I want to give a couple of things and Inter we got Jacob over here Jacob is one of the instructors here at coder Foundry he's going to be doing some coding today I'm going to do some coding day and Jack Kevin's gonna make sure that we have a show so thank you Kevin produced this thing I won't be here a lot yeah yeah I'll just be hiden yeah um and so what we want to do is talk about like if you come to school um either in January or if you come in self-pace soon what can you expect from coach friend and this is kind of like that but super fast so like uh this normally we would teach this over 16 hours of construction what you're going to see today we're going to try to code this in what four you think Jacob what do you think yeah I think we can manage it in four hours probably get it done in four maybe a little fast but like uh also to um to give you some kind of scope too this is kind of the middle of what we're going to teach when we go to Blazer so this isn't the first thing we do so if you're like hey I'm just new to coding I don't need to got him cutter founder there's a lot happens before we ever get to this point um so this is primary to demonst straight Blazer and show you kind of what it's like to build a Blazer app and then um and if you want to learn from us just know that there's a lot of work that you do before you even get to this app but this is kind of like the middle of the course it's not the beginner it's not the start so but if you're building razor Pages asp.net you've been coding for a while I'm hoping that you'll find this um entertaining and educational me and Jake are going to go back and forth through build a app we're going to use GitHub to communicate at each other even though we're down the hall from each other we still need to do pulls and stuff like that so we get Cod because we're going to do this live and um I'm going to build the UI he's going to build the back end and I think we should come up with a good app here hopefully at the end of the day here so we'll see what happens um I think the first thing we can do is I think Jacob and Kevin we should probably introduce them like what Blazer is in case you're just brand new and you just happen to show up to this coder founder thing and like what are they gonna do so let's talk a little bit about just Blazer real quickly just to lay the groundwork so we can all have a common thing to talk about so let's 's go into some slides here real quick and um this is um building weication Blazer and you may be wondering like what is Blazer and Blazer is a web application framework built by Microsoft now the reason we like this framework is because Microsoft surrounds the developer they have the ID which we're going to use today Visual Studio the language C is primary the language we'll be using and then they built this framework called Blazer allows us to build web applications in addition to that um they have an ecosystem called new get allows us to bring packages in and you'll see us bringing in packages from using using statements when we build our app out today um now Blazer is just a full stack web application devel framework and it's used to build web apps that bring a rich UI of interactivity so me we don't have these massive page loads or refreshes just updates are being sent to the Dom or the page and then it updates in real time without us pushing back now the tooling the components the framework we think makes it really easy to build that applications and you'll hopefully at the end of this you'll say wow okay that's what it takes to build a comp that's kind of cool now what you'll notice here is one of the benefits to Blazer is that there is no JavaScript required or minimal I am going to show you how to call JavaScript Frameworks from Blazer using interrupt um and the reason I'm going to show you that is because in case there is a JavaScript framework you need to use just because you have Blazer doesn't mean you can't use it we're going to show you how to call some of those um it comes in two flavors Blazer web assembly and these basically are lifted out to us with two templates the first one is the web assembly template the other one is called the web app template web assembly templ is the one we're going to use today and this is when we're building just a purely client side application akin to a JavaScript or just a react app that's just front runs in the client no backend and our backend will be a thirdparty API from the movie dbapi but it's not our backend so we didn't really need a server um the web app template will be used when you want to do both you want a server and you want a client side um for today for Simplicity we just picked the web assembly because we feel like number one you can host this app we're going to build on netlify with free hosting which is kind of cool and so if you're a student coming to coder Foundry and you want to show Blazer movie to somebody it makes sense that you could host it somewhere like netfi instead of paying for resources like on Railway or something like that now you may be asking yourself what is WM well it's a binary code format the main thing is it's really really fast and so higher lbel languages can run inside the browser now like C and R rust and C++ and before you get started it's not silver light it's a web standard and it's the fourth language of the web up until this point when we want to manipulate the dawn we can only use JavaScript and since wm's come out now Microsoft has ported C into wasm and allows us to run c um in the client and supported in all major browsers including mobile so it works really well um so just to give you a real quick history Blazer if we have a little app over here you can see we got this little app here and this is our Dom our docu object model and our components and our net and our web assembly are running in here in um web assembly and it can interact with the Dom if we need to go out and get something from SQL or net core web API we're calling this through rest services and that is our web API kind of framework now today to we're going to be calling through web API but we're not calling des. core SQL Server we're going to be calling the movie database we'll make it a little bit simpler for us to do it but same kind of thing holds true so pretend we have this web page over here on the left here and we make a request um to a movies page and then it'll come back and what it'll do is it'll bring back umnet and the web assembly runtime and try to download all that and once that's done any any other calls hit through the HP client rest and then it brings back a Json response so that's kind of the a really high level view of how this works right so we basically make a call out to HB client and that's going to bring us back Json and we're going to take that Json and then we're going to format it and make it look like a movie page right so Pros are runs entirely on the client inside the browser um it's really really quick um can work offline as well so you don't have to be online if you want this to run so this is great for some apps that could run or function offline um it can run as a progressive web app means install it right there on the app on their device it can take advantage of the client's Hardware whether that be an Apple iPhone or a desktop app or an iPad or something like that it can take advantage of that and there's no need for a net runtime on the client machine all of that is inside WM and pushed down to us all right now the Pros also it can update the Dom with C that's what we're going to do today we're we're going to use C to update our Dom and the ne for JS is greatly reduced however I'm going to show you one way to call interrupt and use a colge JS library that we want to do and then razor synex in our markup makes binding elements easy I hope if you're coming from react or you've been looking at angular you'll see right away that okay that's pretty easy a lot of the plumbing is done for us and we just reference very in our code and it takes um it figures out how to bind it when to bind it when to change it that's pretty neat and components built for WM will work for servers so anything that we build today we could run it as a server side component with no changes and that's really powerful all right and also you'll see we'll have complete access to the Net Framework of libraries all right the con is um it's restricted the capability of the browser we feel like this is a good thing it runs in a sandbox just like anything else that runs in the browser whether it be JavaScript or whatever um you got to have capable client hardware and software you know for example it has to have a web assembly support that's required but every major browser supporting that and the download size is larger and the initial download can take longer though Microsoft has been working with what's called tree shaking and only delivering the absolute bits that you need and this has reduced the file size down but there're ALS Al when you look at web app they've also are to tackling this problem by loading it from the server first and then downloading the wi in the background so there's a lot of things going on to make this fast and really speedy and capable application so I think it's going to be kind of a game changer for us so let's go Jacob how you doing doing great excited to get coding you know it's what I live for ready write some code absolutely all right so let's let's um um let's level set what we're going to do we're going to build um Web movie a Blazer movie application do we want to demo that real quick you think or what do you think should we show people kind of what we're g to do um yeah we can do you have it pulled up can you pull it up pull it up and let you do I know I went off script there man so like I just I just you know but like go ahead and uh pull it up and see do let me get it pulled up give me half a second sweet all right so if you guys were watching earlier you may have seen we uh showed this off on the previous live right yep so uh yeah this Blazer movie list we're going to be calling the tmdb API showing some of the popular movies um getting a little bit of Det details about it we're going to be able to browse by genre we've got our action movies for example we can take a look at just our action movies we have page of nation involved so you don't get a page of you know hundreds of thousands of movies at once um and it's going to be purely client side we don't need a backend we're talking just to tmdb so it'll be a fullon web assembly app I think it's pretty cool yeah cool all right awesome all right so to level set here um one of the things that we'll do is we'll start off with building this thing from scratch and I'll let you take off with the project setup and just let people know we'll go back and forth um and when you'll hand off part of the project to me we'll be using GitHub to transfer our code between each other just like we would in real life so we're doing a couple things here we're building a web app we're also simulating like uh a work environment here kind of like how it works and in real ways this is kind of how we built this app even though we're down the hall from each other we were uh sending stuff back and forth through GitHub so uh we thought it would be appropriate to build it we do think that um if you're starting out and you're new to coding um this may be like up here that's okay uh remember this is the middle of the course if you want to come to Cod founder it's teach you everything they get you ready for this if you don't know if you're ready building an app like this is what employers are frequently more and more asking because the API is easy to distribute to the candidate and it shows that they can lay out a a page and then call an inpoint and get some results back and where that endpoint's from an API or a database really doesn't matter that much when you're testing a candid see if they can code or not so I think um an API apps challenges are more and more frequently we're seeing that all the time so we want to make sure that you know how to build one so all right well look man I'm going to let you code now so we'll set it up sweet and then when you're ready I'll come back and we'll talk again so have at it Jacob go show the world what is all about beautiful all right well let's get started let me pull up visual studio for everybody here um and we're starting right from the beginning this should be a familiar screen to those of you who've written anynet in the past but I've opened up visual studio we're going to create a new application and there are two Blazer templates that um you'll primarily be using in net 8 you'll see the Blazer web app template that's new in net 8 as well as a Blazer web assembly Standalone application um and the the biggest difference between these two is that our Blazer web app template will give you a backend somewhere to host your application somewhere to do serers side rendering um all the uh render modes we've spoken about in the past are available to you a web assembly Standalone app is what it sounds like it's it's more akin to your traditional Spa application so it's a client side app there's no backend involved and since today we're calling someone else's back end that's the Apple pick so we'll choose Blazer web assembly Standalone um the biggest concession we'll be making with that is that we only will have our web assembly uh render mode so we'll select that one we'll give our project a name Blazer movie alive and there is there's a few options when we're creating a new application things like authentication type that's a very common one um one of them that typically is checked by default is this include sample Pages option I would say for anyone out there who's new to Blazer I do recommend starting a project that way it gives you a lot of great code examples um shows you kind of how Blaze your fists together to build an application and gives you a barebone starting point we kind of know the direction we're heading so I'm going to skip that I'm going to get those out of my way and we're just going to start with a bare minimum Blazer web assembly application in net 8 all right we're getting loaded in all right we have our new application visual Studios up and running and just to show you guys this is a regular old web application that means um it's just HTML CSS uh with some web assembly magic um so I'm going to get us started we can see we have a ww rout that should be familiar to you net developers out there that's where we'll be serving up our static files things like an index HTML page our CSS our stylesheets um we have our components folder here as well that's where all of our Blazer components will live we'll be T touching on those a little bit later but um that's a little bit new if you haven't used Blazer before and a program CS that's a every net application you should you should be familiar with that if you've been coding with net um but we're going to start just by setting ourselves up with some tools we like to use here at coder Foundry um so we'll take a look at our index.html uhoh and this should look very familiar to any web developers we've got here a regular HTML page and this is actually the content that gets served to our browser um when we visit a web assembly app we've got our HTML tag our head tags with stylesheets our body tag and uh our magical web assembly script um so when this app runs just like a typical Spa application single page application this HTML is what your browser is going to see uh including this loader right here this is we'll see this in Action a little loader to indicate the web assembly is getting started once it hits your browser this script right at the bottom are blazer. web assembly. JS that's what does the magic and kicks off our uh web assembly runtime um we can take a quick look at this this is a very simple web application um that they give you like I said I didn't want sample pages so my really got out of my way with this one and we can see there's our loader we're loading up our uh web assembly and we get a Hello World welcome to your new app step one of any new application hello world um but I'm going to go ahead and pull in some resources we're going to need um because this is just HTML CSS the regular web development we're used to we can use uh all sorts of front-end framework tools we here at COD Foundry we like using bootstrap a lot um but just as easily you could use Tailwind or any other CSS framework of your choice um but to start with let me just pull in bootstrap that's always our first step anyways um and it's just just to make things quick and easy for us we're going to go ahead and use this BS CDN so we'll copy over our uh bootstrap link right into our head tag just like normal HTML all right part one and of course to make sure bootstraps working smoothly we'll go ahead and grab their script as well one thing to note about um Blazer is that once this web assembly script runs Blazer has taken over with the uh web assembly runtime and the only way JavaScript is executed is once we call it from within the runtime but to make sure that our bootstrap JavaScript is able to initialize uh without anything special from our code we'll go ahead and put it above our assembly script so that it's already loaded into the Page by the time we make it into web assembly comment it up make our code a little bit easier to read all right and up next we'll grab a couple other resources that we like to use here we're going to use our uh bootstrap icons as well if you're not familiar bootstrap icons gives us a lot of um readymade easy to use icons for your UI we like to use it a lot here um and again we can copy it in with the CDN uh but hopefully you guys can see that if you have some other icon pack of choice um font awesome is a big one it should be just as easy as sticking at any other vanilla HTML page um let's see another one we're going to use we also use uh Dev icons these are some icons that use um or that that show off some tech Stacks that are a little bit harder to find and we use this pretty frequently so we're going to pop this in here for ourselves and I'm going to go aead and grab some fonts as well I know built enough apps with Bobby to know he loves couple of Google fonts uh monot and babis new that's the wrong one so I'll bring those in here once again just as easy as any other stylesheet or any other uh front end tools we can bring in just sticking them right in our head tag um and of course we have the option of downloading these as well and sticking them in our ww route if you we prefer to avoid cdns um let's see we've got our app.css that's our default Global stylesheet that comes with blazer um comes with a little bit of styles that's how we saw that spinner uh when we first started our application um this link tag right here links in our compiled CSS this is not a stylesheet that we can see right in our solution Explorer like most of our files um but we'll see a little bit later on that Blazer supports what we call isolated CSS so we can write stylesheets CSS isolated to just one component or one page and Blazer does a little bit of Magic by compiling that CSS for us um so we always want to leave this one in so we'll go ahead and comment that for ourselves all right I think that is all the stylesheets we like to use we've got bootstrap our icons Dev icons our fonts bootstrap script all right now I got to add a few more files to our uh our project um one of the things we use here at Crudo Foundry a lot we've made a a stylesheet we call our themes CSS that gives us a a handful of color palettes kind of for free if you guys are like me um picking colors or a color palette for your project is just a nightmare every time it drives me crazy anyway um so we said well let's just do it once and reuse it so that's what we're going to do here I'm going to bring in a themes. CSS um it's one of our uh one of our resources that we provide to our inperson students as well just to make our lives a little bit easier going forward um so we'll load that in there just another CSS file into our ww route again that's where we can serve all of our static files so that we can display them in our application and we'll link it in here to the head of our application again beautiful all right um we can go ahead as long as we're playing around with our index.html we can make sure we're super professional we add in our own fabcon as well one of those details that uh is often Overlook said it and forget it beautiful go ahead and Link that in as well all right image okay got our fabricon we've got our stylesheets okay all right we've got our scripts in here and while we're at it we're going to add a few more things here we're going to add a uh JS folder here Bobby mentioned earlier he's going to show us how to um to use what we call JS interop called JavaScript from within web assembly which is a really cool thing um so I'm going to go ahead and add our library for we're going to be using vanilla tilt today so we'll plug that in all right and then Kevin was kind enough to make us some images ahead of time so we'll go ahead and bring those into our project so we can use them as needed yeah saw those okay all right so I think we've added all the tools we need um let's go ahead and see see if our bootstrap is working as expected we'll run this make sure it all works correctly um so of course this index.html is when the application starts up and then web assembly takes over from there so it is a single page application um and within our components folder we'll see we have a Pages folder as well they've given us one page to work with something to start with once our web assembly takes over here's our Blazer code that is going to be displayed like we saw before hello world welcome to your new app uh and so far this pretty much just looks like HTML which is kind of the beauty of Blazer uh we got something new up here we've got our at page is going to help us with routing we'll see more of that um but for the most part this should look familiar this should look like regular old HT ml um important to note is that these pages that we route to in Blazer when our components are displayed uh they get plugged into our index.html um within this first div we see here with the ID of app that's how our Blazer web assembly knows uh where to put its content you'll also see here div with the idea of Blazer ER UI so if some exception is thrown if we write some messy code or something goes wrong wrong uh this is the HTML that gets displayed because at that point the web assembly has to stop running so um plain old HTML kind of our backup for when web assembly doesn't run um but when it does we'll see our razor Pages our Blazer components get plugged in in this ID of app um so let me just see let me make sure bootstrap's working a little bit I'm going to go ahead and give myself a div with a few bootstrap classes uh just to make sure it's imported correctly and we see everything right so we'll do the hardest thing in web development we'll Center a div give ourselves a good old h100 to fill the screen Flex box um I still want this laid out vertically and we'll Center it an line item Center little bit of bootstrap magic and as long as I'm testing I'm going to go ahead and put in a uh a button this will show me not only that bootstrap is working but our themes. CSS should also uh style this button up in uh our own color for us so we'll say uh primary button and we'll make sure that our images are pulled in as well so let's see Slash Images slash the movie DB that works for me and we'll give it a little bit of space uhoh all right let's run this app and see what we've got so far now that we've included all of our our uh HTML goodies let's see if we got this styled up nicely okay oh not BTN dark autocomplete got me just a BTN that'll fix our button hopefully our image pulled through that's excellent it looks like our uh bootstraps in here we've got our different font from bootstrap and we did we got a bootstrap button uh if you've used bootstrap before you'll see this is not bootstrap's primary color the the blue we're used to seeing from bootstrap um which tells me that our themes. CSS is loading in nicely which is excellent excellent we're off to a good start we're horizontally centered we're not vertically centered so I guess it's time for some CSS we got to fix that up um so let's take a look real quick because our page doesn't have a lot of content uh it's vertically centered within our div of ID or with the ID of app um but we don't want that we want to make sure that it's centered in the page so we're going to go ahead and write some CSS to make our body tag fill the page and our app tag fill the page um and then we'll set ourselves up with our little coder Foundry starter kit um so we'll pull in our app. CSS this is our Global Styles um and you'll see there's a lot of CSS written in here already this comes free from Blazer um includes things like validation form validation uh styles are in here um that error UI we saw earlier it Styles up here and that spinny loader we saw at the beginning um so I'm going to leave those alone we're going to add to them though so go ahead and use our regions in uh Visual Studio to hide this from me don't want to touch it and I'm not too worried about it don't have to think about it end region all right so let's giv ourselves a start I know I'm going to need a root of our CSS um if you're familiar with CSS you'll you'll know that's Ty Bally where we're going to put our CSS variables that we use frequently um I'm going to come back to that let's fix our height problem first we're going to give ourselves uh HTML and body selector here to fill the screen 100% nope not Auto 100% And um yeah we're going to give our app the same thing we're going to add more to that one all right hopefully that'll fix our vertical centering problem let me take a look boom right away yep we're vertically centered good to go our tools are all brought in I can see our images are showing up um let's add a couple of our favorite favorite customization here um Cod founder here we like to put a lot of our basic Styles in the root um just to make it easy for us to change the look and F app as we go we kind of Define our fonts sizes and colors all in one place so we're not changing hundreds of lines of CSS when we say you know what actually I don't like the monster op font we picked or maybe that font size is a little too small um so first thing first let's define our fonts we're going to have ourselves a title font Bobby's favorite bab is new and for our backup we'll do sansera for all these um and a body font that's going to be monster rot um we also like to give ourselves a couple colors we found uh typically in web development that a pure white and a pure black can make things hard to read or be a little too much contrast when you're visiting a page so we have to give ourselves a uh dark and a light color that's almost black and almost White and our dark color for me we're going to do a 21 21 21 almost black and we're going to give ourselves a Almost White and then we'll give ourselves a the uh uh some textiles so by default we're going to make our titles uh our dark color and we'll give ourselves a default font size of one R all right this will give us a nice central location to modify the Styles as we go if we need to um we're going to go ahead and give our body the font family that we like CF body font and our font size right here we'll go ahead and add a couple of styles for our headings we're going to do H1 through H6 and we're going to use our font family of our title font it's good suggestion Visual Studio but not quite what I want and um just a quick fix here well let's take a look let's see how this comes out okay I can see our font has changed let's give this a double check [Music] here okay all right and one things that you notice right away when we've loaded the page here is we've got this box around our H1 our Hello World um that's because Blazer by default we can see where we configure it will focus on a selector for us so that uh to make it easier for accessibility uh which is great I don't want to disable that but I don't want this outline here so um by default it's going to select an H1 and I want it to not give me an outline so when it's focused outline none yeah you got it all right let's double check this okay all right sweet we'll refresh the page let's make sure our outline is not there and then I think uh we'll have a nice set up for Bobby to feel comfortable his favorite fonts his favorite bootstrap his favorite icons feel right at home awesome beautiful okay okay excellent let me uh get this in GitHub uhoh and uh hopefully Bobby will feel right at home in this project when he poses changes okay all right I think we're pushed I think we're ready to go um let's see Bobby are you out there I think I am all right sweet well I got off set up for you I added all our Frameworks got our fonts in there our favorite colors our themes icons I think you're set up you'll feel right at home all right you hear me yes sir all right let me get back over to my screens here all right so uh the next thing I want to do is uh talk real briefly about what we're going to do next the next thing we're going to do is like really get into Blazer at this point and we're going to add our first level components but I thought I would take just a brief minute to explain what a component is in Blazer and how that what we're going to do so what we're going to do is as you can see he's got a web page that doesn't have any styling on it we need a menu we need a maybe a top nav menu going across the top and maybe a footer menu um but to explain how that works I think it makes sense for us to um talk about components at a high level so we can kind of know what's going on so me get to my here okay all right so um when you're talking about Blazer components a lot of times people are only interested in the render modes and like the render modes are important um we're showing you the wi is and render mode today um but really why you'll stick around is because of bler components and how you build it and the one thing about components is they run server side or client side doesn't matter what render mode you're in really you can decrement them and tell them where to execute but for us to understand it there's kind of um may want to know what a a web component is and it's really just a reable UI building block um it's got HDL markup in it it's got some CSS and it's got some C code now what you've seen at this point is a page that he had you showed the homepage there and it's got um some as markup in it and it also can have some js code as well so Blazer has five main types of components um the first one's the app component we'll look at that a little bit here um and it contains That Base HTML body tag the app component primarily only is used in the server application web template in here when we're running web assembly we don't really have an apponent we just have one index page um then there's a router we're going to look at that today where how routing is figured out and like how does it know where it P page to go to and how's it route it's pretty easy for us to create those routes and then we'll show you real quickly how that's done and then there's layout components and that's what we're going to build in this session right with me is the is the NAB bars and the Footers and the elements and how do we lay out a page so that we don't have to put like a menu on every single page that we write we just want it to be injected in a certain spot and then our surrounding elements that be their footer and everything else is kind of is along for the ride then we have the page level and pages just go inside of a a layout and we have a homepage right now so we'll look into that and then um and how we can like change that route to it and this allows a page to be so it can listen to it and respond to it and finally we have UI and we have named this component um in fact we're going to have a folder it's own folder and these are custom components are building blocks that aren't pages that aren't layouts they're not a router they just you have to include them on a page and those are kind of our five layout our five components um now what you'll realize is that everything in a Blazer app is a component on it first framework and everything you build and everything you make is a component and this is very important but that means that when Microsoft designing the framework they had to make sure that components worked because everything's a component and you'll see today as we build a few of these over the next few hours that they're clean they easy to build and components um you just know they can execute on server or on the client side all right so I think I can try to get some code here and let me see here see if I can grab this thing here okay so see what we got going on here all right so I'm going to open up my project solution here I just cloned it from GI her repo and so I've got Blazer live here we'll see what we got going on here and what I'm running in in here when you're looking this is Visual Studio 2022 preview the new version of visual studio will come out tomorrow as you're watching this so if you're watching this in the future um just use Visual Studio 2023 all right we'll take a real brief um tour of what we got going on here we've got um our ww route that Jacob went through which with you and you can see here got my CSS I've got all my images in here my Js okay you put that in there cool and then I've got an index page that has everything that I need and this is the injection Point um to our whole app in fact everything and we stress this a lot in a web assembly app everything gets injected inside this app div here so don't erase the div ID with app it's not going to work and that's because of a component and so if we go here and look at our components here we have this app razor and this is where everything is um found and this is how it's controlling round and this component while we can't see the code behind is doing all of the routing and inserting and everything that we need to happen here and so this is the main kind of component um of our app and you can see here that um this right here is this type of main layout and this tells us what the layout of every page that's injected is going to be okay now you can override this on a page by Page level level so you could have a default layout and then you could come in and say okay for this page I want this layout but for our purposes we're going to use the lay same layout throughout our app and layouts are in here in this layout patreon so let's look at this main layout here and you can see here that this inherits layout component base it's what makes it a layout page or layout component and then the app body is what you have to have for all the injections to happen okay now when it looks blank it looks weird and it's like what is this thing doing but once we make our own and maybe that'll make more sense so let's go ahead and make us a brand new layout to see if we can change the look of this homepage here so this homepage um currently right now just says this home and his hello world in here and you notice there was no kind of chrome around it un let add some Chrome to it so I'm going to come over here and I'm going to add a brand new razor component here and I can call these components whatever I want but I'm going to call mine top a layout and I'm going to call all my layout components I'm going to make sure they end in the word layout and call it whatever now of note if you're at um cerr and you're coming through our course um we have a whole course um in the Blazer class it's going to be just focusing on doing this and so what I'm getting ready to do it' probably take us a day or two as well to do um this is something that we cover a lot in detail so that you can theme your um applications you can lay them out so we actually built a top nav and a side nav but we can't go live for three straight days you know we'd like to but you know leave that for David Blaine when he freezes himself in ice or something like that so um and so we're going to have our layout here and you can see here the layout is just a HTML and it's also got a code base okay um and remember every layout page um has to inherit component base so I'm going to go ahead and set this up to make this a layout page that is kind of the base thing that we need here okay and then from here um I can build this however I want I can make a any kind of HTML I want so I'm going to get rid of this H3 class we don't need that and I'm just going to start laying out the framework or the Chrome around my app and so that's going to consist of a div and I'm going to say deflex this and this is bootstrap I'm going to make this kind of flex column here and so I type so before um I type that completely wrong said 100 before we get started much further let's show you kind of what we're going to be build here so um I think it's worth noting that sometimes we can look at kind of like our apps that we want to do and I always draw wireframes when I do that so I want to share with you kind of the wireframes that we're going to use here and that way you'll have a visual of what I'm trying to do and it may make more sense right all right so let's go over to here okay so we've got this um wireframe that we've got put together here and [Music] um and this is what we're going to build in this session we're going to build this kind of like this top nav here and this is going to be just kind of like our logo and then one link here and then inside the middle here we're going to use flex box to flex this so that our main content AA flexes to fill all available space and then finally we'll come down here and we'll build this kind of cool footer that has maybe a copyright maybe our logo of our app and then maybe some um some Social Links and so that's kind of what we'll do in this session and then when I'm done with that we'll give it back over to Jacob and we'll actually start bringing data in from the the T um the tmdb API so this is the basis for building all apps here at codr we believe in making them look good versus just building it because if you turn this into an employer as hey I want to work here and it looks like junk then you know what maybe they don't pick you all right but the person that goes through the effort to do this so we feel like there's a lot of value to be played into like how does this how do we make him look good in addition to coding it up so all right so let's go back to our code base here and um we're back in here into our um our our div here and so now let's make um our layout here so what we're going to do is this will Flex it into multiple columns and so what I need here and I'm going to lay out with some things here I need a top nav here and um I need maybe a main area main area and I need a footer that's our three things that we're going to build now I'm going to build this top NAB with a component but I can go ahead and add in my main um classes here so I'm just going to put atic tag in here a main tag and then I'm going to put a footer tag in here and um we're going to put a component for footer in here and we're going to build a top nav component and then inside the main tag we're going to put our at by here don't put our at body in there nothing will render okay and then once we got this laid out to make sure that this grows I'm going to put a class in here I'm going to say Flex D gro-1 now you can if you're familiar with flex box you could have done this with CSS this these classes here that we're adding are the flex utilities built in the bootstrap so if you use other CSS Frameworks you can use whatever CS framework you want um we use um bootstrap here quite a bit and then I'm going to add one more here I'm going say class equals say flex and this will make it shrink so what this will do is make this footer always at the bottom of the page and the main will grow as big as it needs to grow and um so this is called a basically sticky footer okay now because our top nav is at the top it will always be at the top and as we scroll um so this is our basic kind of flex layout here pretty simple all right so the first thing I want to do is I want to add just a another component and I want to add a main nav component right here at the top here so let's add another component here I'm G say add new razor component and we're going to call this top nav menu now you may be asking why don't I just put all of my code into this layout and you could um but the reason we separate footer and menu is that sometimes menus in general can have code behind them as well maybe you need to render links from a database or something like that and so it's good to separate these kind of things now you could just put them all in there if you want but you don't need to uh we like separating it we think it makes sense to separate them okay so in here this is not a layout component it's a menu and so we can just do markup we don't need to include anything in here so I'm going to build a NAB here I'm going to use the basic bootstrap Styles here and it's just a Navar and when you do bootstrap for 11 kind of know kind of what they're going to do so I'll explain these as I go but this isn't a bootstrap class normally if you were in the school we would we kind of go through and how these kind of work but it doesn't matter at this point um we just want to get this into our page as quick as possible all am using GitHub copilot so if you see it recommending stuff this is coming from copilot so sometimes it helps and as Jacob shows you sometimes it doesn't so which is okay now one thing that we're going to do here is um we're going to make this a container and one thing that we have adjusted here at cutter founder is containers pretty much are going to be XXL and what that means to us is that the container will um stretch to fill all available space except on the super large ones and then I'll put it in a um have some gutter on each side and this is to account for these Ultra wide monitors that you see coming out these 34 45 inch 50in curve monitors and if you took your web page and they're looking at it as a full screen then your menu would feel like you know it's three miles to the left or something like that so this will allow it to be kind of look pretty good on all menus or all screen sizes right so that's kind of what kind of what we've adopted here now the first thing we can do at the top of our menu here is add an a tag and this is going to be just a reference to our homepage and um homepages in Blazer are always with the backs slash and we need a rout with back slash and that's our home route and then I'm just going to name put a margin on this little space and this will be just a image that we're going to put in this a tag and you can see here co-pilot is trying to tell me what it wants to put in here but I'll take it and change it doesn't finish it either so you have to really watch copilot sometimes he's your friend sometimes he's not and what we want here is instead of the movie DV logo um we want to [Music] use orange Blazer movie logo and then we're going to take this class out here want that and we'll say height 50 this is just put our logo in the top of the page pretty simple okay the next thing we need is a button and this button we're going to build is our hamburger menu when it's small okay and it needs a class of navbar Toggler and we got to give it a type equals button and then there's some other ones that make it work is data- bs- toggle equals and then collapse I need a Target I probably should have copied this if you're listening to Jason but yeah what we can do here our Target is the ID of the menu whatever we call it and um we can just say [Music] Navar um movie Whatever Blazer BM we'll just say Navar BM for Blazer movie doesn't matter what we do it matter what we call it and there's a couple of other ones that we put in here it's expanded and we'll say false that readers know that this is by default not expanded and same thing we'll give it a label this gets kind of long sorry we'll say toggles the navigation like that these labels here are for readers and for visually impaired this helps tell it what this thing is going to do okay and this is right here necessary because this tells us what a Target and this tells us that it's going to toggle on and off and open and close Okay so that's our button and then inside of our button we need to give it something and in bootstrap it is a span and we just say class equals and this gives it that threel kind of um hamburger menu you can replace it whatever you want but we're going to use theirs I think that's it this all works when we're done then next we build our actual menu and this is just a simple menu and we'll say say class equals and this is say going to say collapse so it knows when to collapse it or not the class collapse and then we give it an ID and if you're playing along at home this ID has to match this target here so we'll say Navar DM almost done here and hopefully this will will be really cool when you see that what we're doing here give it a CL Navar nav emmy- Auto tells it where to start we're going to push it to the left if you said Emy start um Ms push him to the end fancy little margin on the bottom and then if it's on the large Bri point zero okay work and then finally Li inside our UL so we can add as many um item want to this menu but we're only going to have one today now we're going to use a bootstrap component that's built into the framework okay and uh I liked it okay I didn't do right was make sure the HF is slash what this match does is allows it to when it's selected make it um bold and white and then when it's not selected make it the default color and that's all what this does so you don't have to figure out how to set the active state to all these menu item just use nav link it's built in it's kind of cool and inside of here I'm going to add an icon to this home here and um there this and because we add a bootstrap icons and I know Jason Jacob did it I know that I can do this and I've you'll memorize some of these icons if you use any kind of icon for a while if not they have great documentation you just go look them up as soon as you want but it basically stands for a bootstrap icon and then what type or the name of it and it's home so this put a little house beside there okay so that's that okay so we can save this and now Watch What Happens here so if we go back to our top nav layout check this out so now I can say top nav and then look at this it already knows that I have a menu component and this is one of the things that we like bringing up is that this this environment that you're in this app hasn't even compiled yet and um it's already recognizing the Styles so or the components that it can do so now we have a topnav menu component an appbox and an app footer and then to get this to all work we come over to our app razor then instead of using main layout watch this pick our top knv layout here our top nav layout here now I'm good some days I'm okay we'll see what happened plate work okay look at this so we've got the this image here and if I go over here probably if I highlight this it's it's out there but um you know it's white and it's not dark and that's because we didn't put any styles on this so probably need to add some Style on this but guess what it added this menu bar I think so let's style this up a little bit more I will F disclosure there has been some issues with um hot reload Jacob's machine works better than mine I don't know why maybe it has a cooler computer than me should talk to management but um we can uh basically uh close this down here and maybe we can come in and get this to work so let's see if we can um style this menu up now here's the other thing that's really cool about components is that each component can also have its own stylesheet and this is called isolated um CSS and the first time I saw this I didn't like it because I was used to managing my CSS in one file and I'm like why would I want isolate CS my CS is spread all over the project but since I've used it I've come around to that in that now I can write styles that impact only the elements in this component so I can guarantee my component is going to look like the designer intended now still to this day whether you use isolate CSS or use you know um one giant Styles sheet or a collection of 20 doesn't really matter you still have to communicate you still got to make sure you don't um override it but the cool thing about isolate CSS is that it cannot reach out and affect any element that's not in the component which is kind of cool which means it can't impact the body tag for example the body tag being in the full page it won't allow it to go that far it can only impact the elements that are in here so these navs and these divs and these classes that are in here is the only thing that it can do all right so let's add a stylesheet to it and so it's pretty easy to add a stylesheet I'm going to go to the um layout folder here where this component that I want to have a sty sheet exists right here at the root level and I'm going to say add I'm going to say new item and I'm going to pick stylesheet now it does have a naming convention and so the stylesheet here and I'll move it to the side here is of the same name as this so I have to name it the same so I'm gonna say pop nav menu. Razer okay then CSS so it's still a CSS file it has this name so that when I add it um you can see here it's now nestled under here so if you're doing this and you're trying to code along at home or whatever you're trying to do this on your own and this goes somewhere else um it's either named wrong or you didn't put it at the right folder but it should be nestled under here and you can see it puts a body tag in here but it can impact the body tag it only impact um what's in this component its parent it's kind of cool and then um if you over here and look at index when I compile this the styles that are in this component over here are then injected into this Blazer movie lifestyle CSS our project compiled CSS so if you want to see if your styles are being pushed into the project this is the style that you can see in your chrome chrome debugger and then you can look in there and see what styles are being pushed in there all right so let's write our first isolated style we don't have a whole lot to do here so I want to make a nav style call it nav style I'm just going to make one here and then we'll add it to our page and I want to set the background because you notice it was white I want a dark menu and I am going to use CF styles that we're used to doing so and um I'm going to go over there and show you where this came from real quick so if you go over here in this themes that Jacob loaded in his project um right here this root here has a bunch of color colors in it okay and then it's telling me what this color is now right here at the top of our root and this is how our themes work is that we set up our themes and you only use these words here and then we apply the theme that we want to use in our case we're using this theme we made up called CF code magic it's kind of like a dark green with some um yellow to it kind of cool but you can see if you go through our themes here there's a lot of colors in here that we've put together okay but we're using Code magic um we like that one it's kind of cool it's a new one that we've built out and you can make your own by doing what we did all right so now I know just to let you know that this is where this color comes from because we're always operating once we're in our codebase on CF theme if we're adding a color okay now the other thing that I want to change is um I want to change the class Class A bootstrap class override it Navar dnav and um we won't see this but we only have one link and it's always active but um can I just want to show you can override the bootstrap stuff too as well so it has all CFS variables that we can also change and um we're going to pick our theme 400 and we do this all the time and we know that our theme is our middle color that's the color we want to pick all right so it's kind of universal when we coat it this way and we just change it from blue to green to red to orange to Yellow to whatever it just changes okay let's run that oops before we do that while that's doing it we'll stop it let's uh let's actually add our style to our page here so I'm going to come in here and add our na Style and because I did that I should I hope get a na bar now see what happens cool all right so you can see here got this cool bootstrap thing but I don't have a nav menu item yet I must have did something wrong so let's look at it should have copied it so let's see your class nbm hey Bobby if it helps I think you're missing um so I got to add a class here to this and this nav item I must have an it a nav link and that should do it see if my hot reload all right shut it off all right so we'll run this one more time we should have a nav bar in place at this point all right cool maybe not nothing like live J Jacob knows why you that Jacob yeah yeah yeah um I think in your datab B Target on that button I think you're just missing a pound sign your line six yeah the datab target up there I think it needs the pound sign in front of it can you hear us w we he can't hear us uh uh oh oh hold on hey Bobby you can see this but you can't hear [Laughter] us you even see us he can't see us either he's in the code zone so what's the over under on how long it takes him to fix this messed something up and I don't I don't see it what you got Jacob can you can you hear us you can't hear us I'm there hey can you hear us all right yeah I can hear you now what did I do wrong okay Jacob's got you yeah it's your your line six on your datab BS Target you're missed the pound sign oh I'm an idiot okay great it's an ID okay yeah thank you all right let's go thank you live is awesome in it there we go go home okay cool all right so we've got a menu thing and now we've got our hello world we just need to add a footer now and then we're golden what I want you to understand this is going to be injected on every page as we go forward so it's kind of cool and um so let's go let's keep going and so I'm going to add a new razor component and then we're going to add footer in here and let's say footer call it whatever you want I call M footer exactly what it is and there's a little bit more work here to do um not a whole lot and so if you look at our footer we have three columns and our left column is going to be our um our copyright we're going to put a logo in the middle and then we're also going to look at our social links on the end so kind of cool we think you should brand everything you make so I'm going to just add a class in here and I just know kind of what these are going to be and I know that I'm going to call this footer style because I made a nav style so I'm going to add a footer style we're going to have that eventually and um this we may or may not use we'll just put it in here and um that's our base setup so we have this wrapper and I would imagine when you're building components you always wrap it in something I think it um that way you don't have to rely on the parent wrapping it so make sure that you're always wrapping it here um what I've got here is two divs my outside div is going to be my back background that's going to go edge to edge but I don't want my links to go edge to edge I want my links to match the container in my footer and so I'm going to put a div in here do that I'm going say class equals inter- SXL and that's going to be my inside container and this is going to hold all of my links and so in here and um one thing I like to do quite a bit is scaffold out when I'm writing these divs is I'm going to say a row and inside that row let me get three columns so I'm say Do class equals column then I'm going to come back and change them I've scaffold these out real quick and um and that's our three columns so one the column one on the leftand side is going to be our our um copyright we're also going to say built by tag I think that's kind of cool and then we're also going to manage these rows as we go into um or these columns as we go to Across the bright points from Mobile to tablet to desktop whatever and move them around make sure they're always kind of looking kind of cool right so what we'll do here is we'll set this up so in bootstrap we have this thing called roog calls which allows us to determine the stack on mobile we're going to stack these on top of each other like that and then um when we get out to say tablets we'll make it three and that'll took them side by side something we'll do and then we'll go ahead and Center this and couple other things here too as well while we're at it um line items and in case you didn't know this everything in bootstrap and a row level is a flex box so we can use flexbox um things in here and this is going to line the items in the center force or in the center like this up and down okay right nice all right so let's work on a quick Row in here inside of here I'm going to have a row and I'm going to make two columns in here again copile is trying to tell me something but it's not what I want so I just ignore it and um column-1 12 means make a new row every time that's what we're going to do here we're going to make sure these stack on top of each other um so it's probably not necessary to um do this but it it kind of works all right so in here I'm going to put a span in here I'm going to make sure this is all in one row or try to be and um we'll say mc-1 and this is a margin of it and I'm going to use built by maybe a colon maybe not we'll just leave it like that and then here I'm going to put an image in here and um you can see here the ID picks up my project um now what it does wrong is it tries to put that in there and we don't need to do that for good strap but say markor logo and when it adds it images don't show up when you're doing this and you have them in your ww route this is the proper pathing for laser projects okay and then I think I can set the height here it's kind of arbitrary um based on your logo but for this logo it's kind of thin and not very very tall so I'm going to set at 30 and makes it kind of readable all right and so that'll be one line I'll say built by and I have a logo here and then we can just do a copyright here at the bottom here at this will be copyright and then we'll put the year 2023 in here and then our coder Foundry guy is Mark Spectre um we're Marvel fans here if you know who he is great it's kind of a deep cut but no that's okay too right so we have um this column here which just has some HTML in it okay so I'm going to collapse that column for now and I'm going to work on this next column here and this is just going to be kind of the middle of it and it's going to just be an image in here so I'm going to make sure this is centered so I can use a bootstrap thing here called Center then um I'm going to put an image in here this is going to be my blazer movie logo when we put up top again what does that but it does equals I think 50 will work all right then right under that if you're using TV tmdb um we need to give attribution credit if you want so they don't shut you down so we're going to um put a div in here and we'll say powered I and then I'm just going to have an a rank f equals this has to go out to their link so this is what they require for you to use their API so I think if you're using your API you should do it the ask they give it to you for free movie smovie d.org all right and then in here um we can put their logo in here they they're trying to get up Cil it again it's trying to tell me stuff and we loaded in the logo here and it's height equals probably 30 I think maybe 10 maybe I don't know small hopefully that works see here this is div okay so let's put some classes on this and one thing you can do in boot as well is like once you're in a column or another div you can Flex the items inside the div here by using deflex and I'm just going to make sure these are aligned and say Flex W if you have to and give it a one Gap so that'll put the power on top of image if it has to if not try to keep them side by side all right all right so that's kind of cool all right so I think that works hopefully all right so the next one is our Social Links we're going to push these to the end of our column here on the right hand side we're going to make them right a line put them over here and then um I'm just going to create a div here same kind of thing I'm just going to lay this out and um then um make it call 12 now I have a row just one column um and I'm going to make another column underneath this because I'm gonna put some link to some projects or something like that and this is a really good I think footer for a portfolio developer someone trying to break in so when you build a project they know how to reach out and touch you so that'd be kind of cool T hire you for that job so we don't really know what these links are going to be so we'll just leave them blank for now and then here we'll use our icons here I'll say class equals and uh bi and it's bi- youube okay cool and let's see here I think I can copy this and just that's right stick them in here love this one like this in Twitter DX you know it's Twitter and YouTube and then we'll just maybe get up you put whatever you want here doesn't really matter I have the linked in though these blue oners saying hey I don't like the spelling of this but it is right so if this bothers you you can say ignore and that blue underline will go away but it's just a warning it's not really an important thing here and you'll see your warnings down here in your um Spectre is not a word so if it bothers you it doesn't me but if it does just say ignore which is this is a new enhancement it's kind of cool um if you're writing content a little spell checker in there helps you out a little bit I don't know kind of neat all right so let's um let's let's build three more links here I'll take that and I'll change them let's GitHub saying hey what what if you want to put privacy terms and contact in here and I'm like no but I will put blog oo and uh bug tracker gotta got to rip the bug tracker and um I can also add a link a little bullet little dot in between it that's another kind of Aer Sam thing bull okay so real quickly I think I've got this built out I hope so anyway see if it lines up here looks like it's okay right um we'll see so that's my three areas here I Collapse divs a lot even though I have these lines here I do collapse divs quite a bit trying to see make sure everything there's no orphans out here okay um let's go ahead and add a style sheet in this guy so I'm going to add a new stylesheet and uh if it seems like I'm going fast I am um but let me get on to writing some C code here so it's footer. razor CSS got to make sure these are named the same look at that okay and it should put it in the right spot and it did which is kind of cool all right so I know that we're to see our footer style making one here and we'll say dot do the same thing I did up top I'm going to have a background color and a VAR remembered it did but I went too fast it It For the Win um I'm going to go ahead and set the color of everything in here are and then um we have our cf- light color right and then um say footer style a yeah all right and so here I'm going to change this to theme color so we know our theme Dash 200 and this theme the magic theme this will be sort of like a light blue cool and then if it hovers at that copilot cool all right and I know that this a yellow Y in this theme so I'm going to say cor I just know that color there's nothing magic about that I just need the color and then um style and then we'll say bi and this is our bootstrap links and um I'm just going to make sure they're a little bigger because icons by default will be the size of the font and I want them a little bit bigger so I'm just going to change their size a little a little bit and um if you're watching like man I could never do this typ in with Bobby that's fine um I said this normally takes us two complete days to do this right that's pretty cool did I spell that right inline all right so I think that's my style and um got them all in here footer style did I spell them all right footer style footer style all right let's run it oh well well let's add it to our menu here our layout here so check it out I've got this footer class in here now I can and boom Blazer movie component layout footer look at that and if it's green here it knows that it's inside there pretty slick and um let's run it bam look at that kind of cool um my image didn't come through we'll look at that maybe I didn't do it quite right let's look at that but we have a footer down here we could probably style this up a little bit more that's not bad right off the bat but it probably could use some love we can change this a little bit we'll make it a little bit better let's change that let's get that fixed before I send it over to Jacob um see it was which logo was it it was this one yeah it added that Amper Sam there see if Hot reload works for us that's trying to do the hot reload don't think it's going to work which is okay it's okay and now we got our little logo there or Blazer movie but we can work on this a little bit so I'm going to work on that and let's go up here and work on this a little bit and then we'll call it a day okay in this column right here um is our very first column which is our built by Mark Spectre what I want to do is I want to set it to the bottom when it's small and on wide I want it on the left and so I can um just basically say text MD and this will be start so first off it's going to left justify it on tablets for forward okay and then um I can order it last and then order it MD Dash first kind of cool right I think that'll work on that um here let's add a little bit of Gap in here between when they were stacked they were a little kind of like put together a little bit and um and let's check this one that one's always kind of centered and this one's always in so I think that may do it that may fix it for everything I think it's good enough to pass back off to Jacob boom okay so now it's a little spaced out and then if you see uh this go out here watch it'll change change locations kind of cool all right so it stretches out I got one thing here that at Bow there get that fixed so now we got our B our logos in there boom so here's what you got man I mean like um when you come to coder you'll get this and you can apply this to any project that you build which is kind of cool I think it's neat so what I'm going to do is hand this back to Jacob let me make a commit here and uh we'll get back here together if the guys can come back on while I commit this yeah man it's looking good okay any questions so far anything or anybody asking questions here none okay I don't think so all right good all right let me uh make sure that I got I can send you code here all right so session what are we on session three something like that two two only session two got a long ways to go man oh it's pretty much done now thanks for rescuing me on the the pound sign we' have been looking at that for 13 years so like you know yeah um we were talking in chat that's that's real coding for you man the number of times I've been driven Crazy by one letter you know let me commit to Master P it okay you should be able to see it now and grab it all right let's pull okay gotcha gotcha okay so what you got now is you've got your layout and so now what I want to see next is if can you um actually go out the API pull back some data and just give me like just a title or something and I'll design the rest of the the page and lay it out when we come back when I come back okay yeah get some data flowing I can do that yeah get some data flowing do some actual C work build um show them how this works and how that all integrates into the code with the code behind I think that'd be great all right yeah we can do that absolutely all right all right see you in a few man all right beautiful so we've pulled the changes looking good I do like that color a lot this color we've picked Okay so we've got to get some data flowing we did see this going to be powered by the movie DB so um while Bobby was coding it up I pulled up our API documentation for the movie DB um and first things first what I got to know is how can I authenticate how can I tell tmdb that I'm allowed to see these movies you know they they issue API Keys which is extremely common most apis will be protected by some form of authentication um because they don't want just anybody using and abusing this API they want to know um are using it correctly responsibly um are you making money from it they want to know that all that good stuff um so I pulled it up and I see here that tmdb has two options one is to use an API key um in what they call a query parameter and they give me an example right here um the other option is to use a bearer token so that means that every time we talk to this API we're going to include our Bearer token in as a header instead of part of the URL um which I think I generally prefer the it's a it's a more secure method it's it's a little bit newer query strings are old school and we're in blazer. net 8 we're all about new school so um the first thing I'm going to do before I try to retrieve data from this API is I'm going to get my code our Blazer application set up um with what we call our HTTP client that's uh the easiest um most robust method of of reaching out to an API in net World um so I'm going to set up our h GTP Client First here to use this this Bearer token scheme um and we'll get going we'll take a look once I've got that we'll take a look at our endpoint start modeling some data see what we can get through so um I'm thinking what I'm going to start with here is I'm going to make ourselves a service that talks to tmdb um and if you're familiar withn net hopefully you're familiar with Services if you're not I could I could preach on live until 10 P p.m. tonight about why we love services and how helpful they are in uh dependency injection and all that but um if you've taken our course or you're familiar you're you're you already know where I'm headed with these services so first things first I'm going to keep my code organized I'm going to create a folder for this service uh we'll call it Services as is tradition and within this folder I'm going to add a service I'm going to call this my tmdb client um and of course we can use um if you've if you've used hdtb client in the past you know that we could use it directly uh within our code to call the tmdb API I think it's going to be easier to call this API through a service with purpose built methods so as we're using it Bobby and I don't have to remember the URLs or what has to go into the request we just call a method and it'll do it for us um so as I go to write this client we we do have in a Blazer web assembly app if you're familiar with a program CS this looks uh a little bit familiar a little bit different generally on a web application we end up with a lot more code than this but one of the things they give us for free uh through dependency injection is a HTTP client that's configured for The Base address this app is being served from so if it's on netlify it's going to be appointed to netlify by default if you're on Railway it'll be pointed to your Railway deploy by default um but because this is already a service we can use that means I can utilize it I can inject it into my own class here my tnbb client so um we'll get started dependency injection is pretty cool um let me just ask for it and it'll be configured and given to me so I'm going to give myself a private field to hold this HTTP client so that all of my methods here can access it I'm going to give myself uh give it a name _ HTTP client to let me know it is private um and we'll use oh copilot's good we'll use a Constructor injection here this is where we'll ask for a instance of this class to be injected for us when this service is created uh um and then we'll assign it to our private rate only field and we'll do a little bit of configuration as well that's a good start um but for this class for our tmdb client man github's ahead of me we're going to configure our Base address HB client. base uh oh too many T's address equals in URI is that right is that where I want to go a pgps API md.org three yes so by default when I'm using this HTTP client in this class it's going to allow me to reach out to this URL followed by any other parameters I might need or different paths different end points um but that's its purpose here within this service is just to talk to the API so it's a great start um up next we we good citizens will say what we accept um we're looking for Json as a response so we'll go ahead and say that htb client dot we'll add to our request headers um that we are going to accept a new header value application SL Json um and often this isn't strictly required most apis are going to give you Json back one way or the other um but it is a good practice some apis can give you different formats back some apis won't respond with Json if you're not clear hey I'm actually an application looking for Json I'm not a user looking for a page um so it's a great practice and they do ask you to do that in their documentation so plug that in there easy um and up next I need to create an API key or grab my API key so I'm going to write the code first and then we'll add back in our API key um like we saw in their documentation we got to send that with so we'll say our string API key is going to be no good Trico pilot not quite um from our configuration our app settings uh which means I need to inject those as well and that's the beauty of dependency injection here is that in our Constructor if it's being instantiated bynet through injection um we can just ask for anything uh in our service container that we want so for example the configuration of this application I can grab it right there um and out of my config I'm going to be looking for my tmdb key um and here's a cool trick in C is is we call it the null coalescing operator um you can see visual Studios warning me hey this might be a no string you're converting a no literal or possible no value to a non-nullable type I've said this API key is not null because it can't be I don't I won't be able to authenticate if I don't get a API key back um so you are able to use a null coalescing operator to say hey if that's null provide this instead and in our case I actually don't have a backup I don't have something else I want it to be what I really want to do is I want to know about it right away um so what I'm going to do here is I'm going to actually throw an exception this will stop my app in its tracks and warn me uhoh your tmdb key was not found it's not going to work um which is uhoh [Music] found which is good if if our app starts and we cannot find that API key we've got a problem of course the whole app is to uh its purpose is to talk to the movie DB and if we don't have our key we can't authenticate and we can't show you anything so we're going to fail early make sure that we handle that um and now assuming this has gone correctly I am going to close but not quite add that to my headers client. default request headers um we're going to add to our authorization header a new header and exactly what copilot is suggesting to me we are going to be using a bearer scheme as we saw in our documentation and we're going to be using the API key as our value so that when our HTTP client does make a request it includes just what we see right here in the um in our headers every time I don't have to do it with every request it's just going to be configured this way by default so going forward all I really have to to worry about is what endpoint am I talking to and what data am I getting back which I think is going to make my life much easier in the future um and that is a good start here we've created a service we haven't made any methods yet to call um any endpoints we configured our HTTP client so that we can talk to tmdb correctly um let's go ahead and add our API key uh now this is worth noting if you're familiar with uh net development any server side um development in net we typically use our user Secrets secrets. Json a file that doesn't get checked into GitHub but is available to our project to store things like API keys to keep them private just on our server um this is a web assembly application there is no back end that's in our control anyway this is just a client app so um regardless of what I do this key will be available to the client at some point um I do think it's best to keep it out of your actual code like this so that if you need to change it or send it to somebody else and use a different API key it's one place and it changes the rest of your code but um in this application this key will be visible to our end users if they dig hard enough the nice thing is my key is going to be read only so uh I'm not too worried about it but it is important to know typically if you were putting this in a production application you would have a backend which receives the request from your client adds your API key and forwards it on to tmdb um and if you guys saw our render modes video we actually have a example application that does exactly that on render modes um and there is a branch for N8 rc2 because in that application we do have a backend so if you're curious how that works you're you're welcome to go take a look there um but regardless for our web assembly app I'm going to go ahead and add myself a app settings so that I can use that configuration so we will add a new item um in my ww rout called app settings. Json and again that's a pretty familiar file for any net developers out there um this doesn't come by default in the web assembly application because this file does get sent to the client in the end so um really important to know if you have anything that is top secret uh this will get sent to your client application so you need a backend to keep information private from the end user this whole app is going to get sent to them um so in here because my configuration is looking for tmdb key got to have something with that value and yeah your key would go here in this case my key is going to go here so excuse me for one moment to copy that and paste it paste it there we go all right we're back to my code Okay so we've added our tmdb key we've created the beginning of our client and up next we need to actually make our ourselves a method to call these movies um and I know by default what we want to look at is the popular movies um so again I do have that documentation pulled up for myself and uh right over here we have a popular movie endpoint tmdb has very thorough documentation which is awesome um I can see a few things right away I can see on this popular movies endpoint the actual path that I want to call so that's great I'm going to keep note of that moviespopular easy peasy um but what's really important here is and and kind of the beauty of Blazer here is that c is a strongly typed language meaning any variables we work within our code any objects we have to know the properties we have to know exactly what's contained in that model um JavaScript little less work front on the front but a lot more work on the back will kind of let you make any object you want and try to get any property you want and maybe you do maybe you don't um in our C code we know for sure what response we expect and we know for sure what it needs to be so uh in order to call this endpoint and use it within my C code I need to make myself some models that match this response so I can take a look right here real quick um they will give me some Json that we'll use here in a minute um but I can see our response is of course an object with from this popular movie endpoint anyways it's an object with uh a page and integer results an array of objects presumably the movies with these proper in it beautiful total Pages total results so when I do call this endpoint I'm going to get back a what I would call a page response some information about what page I'm at how many pages there are and then an array of data which is very common most apis you will see page in this way you'll see um instead of getting all the data back you're going to get just a subset if you're talking to the Facebook API uh or I guess not the xapi anymore it's too expensive they're not going to send you back all 200 billion Facebook posts in one request they're going to send you back one page of them and it's no different here uh which is great so that means I'm going to need two models I'm going to need one model for this page of response and then one model for the results that I'll get back the popular movies um and I'll show you guys a great shortcut both indiv Visual Studio why we love this tooling so much um we'll go ahead and hit try it and right here their documentation has given me some really cool uh just a direct look into the Json so I can see I got my page my array of results total Pages total results that's awesome I'm going to copy that I'm going to grab that Json I'm going to use it for modeling here um right over in visual studio all right I'm going to add myself a a new a new folder and I'm going to make myself a popular movie paged response that's the class we're going to make to represent the Json we get back which will give us a lot of great things it'll give us type safety we'll be sure whatever response we get is in fact this data um and it'll give us great intelligence to let us know what's available so when we do go back to Bobby he really won't have to take a look at my code too much he'll be able to just discover what properties are available to him pretty naturally which is awesome uh one of the cool tricks here in visual studi is that we can take Json and paste it as a class and let it do most of the work we want for us so if I head over here to my edit paste special paste Json as classes that's exactly what I want I got my Json response from tmdb an example anyway I want to paste it as a class um and it'll do exactly that we've got ourselves a root object with page total Pages total results and results Visual Studio is pretty smart figured out that that's an array of objects and it gave me that class over here so um we'll make some changes I don't want this to be a class of root object I want this to be a class of popular movie paged response and and this result class is actually going to just be not a result but what I will call a popular movie singular this class it made for me automatically is going to represent one popular movie and then this results property is going to give me an array of those movies so just to keep myself saying I'm going to move this class to a new file don't want it in the same file here we're going to go ahead and add new item popular movie. CS boom all right so I'll start with our page response here this one's going to be a little bit easier um because the their API is going to give us back these properties page results total Pages total results the properties must be named the same that's how um our HTTP client orn net is going to know oh this Json I have that maps to this object that's great um in C though we have some naming conventions that not only make us feel more comfortable as developers but actually carry meaning so typically when we have public properties like this uh they're named in Pascal case they're capitalized and this Json we're getting back is instead giving us uh snake case it's all lowercase we have underscores and it's going to kind of stick out like a sore thumb in our code base and feel a little confusing so we don't have to be stuck with that luckily C is flexible very comfortable with uh working with Json um we're going to use a data annotation we're going to use something called Json property name and we're going to go ahead and plug page in here cuz we know that's what we'll get and then rename it to page with a capital P that way our HTTP client knows when we see page it's actually this property page with a capital P and as far as our code is concerned those are two different things so um this is going to allow our HTTP client to know how to map this Json object we get back so we'll do the same thing we'll say Json property name results and we're going to give that a capital R same thing here Json property name total Pages thank you co-pilot love that um total Pages nice Coop pilot on a roll for me today quick work of this all right so with pretty minimal on my part uh I now have a class that represents our response we're going to get from our call to the popular movies um named in C's naming conventions and annotated with these property names so that they'll match the Json we actually receive and we'll see here I'm getting a warning here non-notable property results needs a value um ins they all have a default value this guy doesn't so if we we don't get results back our code will tell us it's not null even if it is so uh we'll initialize this um and the typical way of uh initializing an empty array in Net 7 and before would look a little bit like this array. empty and popular movie to help prevent allocating a large array that's just going to get overwritten later um but here's a cool feature of net 8 they now have what we call collection initializers so this is going to feel really familiar to any JavaScript developers we can say we know it's going to be an array of movies and actually I'm going to make it a list anyway um but I can just use square brackets we're going to say okay give it a new empty collection to start with so that when it does get mapped it'll be there if it doesn't get mapped at least it's an empty value and not a null which will give us errors so um I'm also going to change this popular movie away from an array into to we'll go with an i inumerable or a list um gives us a little more power it's a little bit easier to work with that than playing old arrays um so we'll make that easy on ourselves in the future and I think that's good for this class let's go ahead and give our popular movie the same treatment just as we did before and hopefully this will go quickly Jon property name not total pages but adult and that's going to be capital a adult see if we can make this go a little bit faster for ourselves all right that got us most of the way there that's awesome multic cursor is a beautiful [Applause] thing all [Applause] right all right we got our backdrop path boom and this maybe null got an array of genre IDs we'll go ahead and rename it got an ID original over popularity poster uhoh didn't get the right property name here and V count beautiful beautiful all right let's see we' got a title that should never be null so we'll go ahead and give it an initializer that way we're not dealing with warnings here um at least where we don't need it release date I don't believe is knowable according to their documentation anyway poster path same deal oh that could be no okay all right and I think with that our model is done um it's beautiful didn't have to do it by hand so I'll take any kind of machine help I can get with that one and co-pilot was on a roll too for me um oh I see a question how do you use multic cursor it's awesome uh yeah alt shift arrow keys will give me multiple uh cursors that I can use and navigate that way um you can also hold control alt and click and do two different places if you don't want them directly lines one on top of the other uh super powerful uh but with great power comes great responsibility it's easy to mess yourself up with that one um but yeah I think my models are okay I hope anyways let's give this a shot that's right a little method to use these pull back our data and um hope it goes smoothly let's see going to head back to my tmdb client I'm going to give myself a method here um it's going to be a public method everybody needs to be able to use it it's going to have to be a sychronous because we're going over the Internet that takes a long time prep to our code that's a sync uh which means it's going to return a task a promise to eventually complete you JavaScript developers are familiar with promises a task is kind of kind of the same thing um and we're going to return probably a popular movie page response in the end we'll call this one get popular movies async um and we don't need any parameters just to get the popular movies so this one will be pretty quick we are going to just uh return our HTTP client is going to call uh get from Json async which is pretty awesome this is a great great handy method that we get to use um we send a get request very common in apis I want to get data I'm not posting or changing anything I'm just getting it back um get from Json kind of does the whole song and dance for us all in one method it fetches our uh our our URL tries to parse as Json and returns to us the result which is excellent it's pretty much every API call in the world you're going to do that response or that song and dance get a response par as Json return that object um we just need to tell get J from Json async what type we're expecting and we are expecting a popular movie paged response now we're going to go ahead and give it our URL I think that's moviepopular but that's Double Check Yes moviepopular boom and that's it that's our API call I think we're okay now we need to make this service available to ourselves give it a quick test and if all's gone according to plan we're in good shape we can hand this right back to Bobby with the data flowing um so we'll register our service we've created this tmbb client we're going to make it available to ourselves uh and the rest of our code here uh by registering it and just like they added the HTTP client we will add to our services scoped service of type tmdb client doesn't take any configuration it just does its own thing uh great now it's available to us and the beauty of using the service is now I can go to my homepage and I can just ask for this service it'll figure out all of its own dependencies for me and I can use it right here go back to our homepage and injecting a service is as easy as inject we're telling our application hey go get this service give it to me figure out everything it needs and we're going to be injecting our tmdb client but we need to use our name space and I'll call it tmdb and uh oh first time we've been seeing these uh Blazer components with a little bit of HTML pretty straightforward um exactly what you'd expect to see as a web developer um now we get introduce ourselves to the the code block the real magical Blazer this is where we can run C interactively in our browser um which is a beautiful thing um it's going to be at code with curly brackets and now this this component is um essentially a class for us we can use this um this code block to run code display it if you guys are familiar with um razor syntax it's a lot of power that we can use here um so I'm going to give myself a private field that is my popular movie response might be null it's possible tmdb is down or uh oh I'm sorry page response it's possible tmdb is down or or something went wrong along the way so have to admit it maybe null we'll call it our movies um and we'll use one of our life cycle methods we will say GitHub cides ahead of me we're going to override uh a method here perfect override protected override async task on initialized async Boom um so if you guys are familiar with any other component Frameworks or or or Spa Frameworks um you're probably familiar with the IDE of life cycle methods um but Blazer has a few uh primarily here we have uninitialized async um this method is going to run as soon as our component begins to render um but before it's done rendering we also have built-in methods that we can override here just like we did um to run code after the component has rendered after its received parameters which we'll talk about later um but at different points of this this component life cycle as it runs the code renders on the page maybe Mak some changes to what's there um but for now when our component initializes we're going to go ahead and grab our movies so um we will'll just say movies equals we're going to wait it's async our tmdb do get popular movies async method and if this goes according to plan my movies response uh will come back have all the data I need which means I can now hop into my HTML and use that code um and the cool thing is my HTML gets rendered whenever these these uh fields that it depends on changes um so I can say something like uh using my Razor syntax at if my movies is not null cuz it may be or it will be until this oninitialized async method me runs um but if that's not null let's just play those movies we'll just make a ordered list or an unordered list here exactly what GitHub or what copilot is suggesting to me if I do have some movies this is our classic razor syntax then um display a UL with a list item for each movie's title in my results that's great for each Loop over the results um put a on the page I can even say else um movies are put a P tag movies are still loading so it'll probably happen fast enough that we won't even see it but if my movies are null if I haven't received a response yet or something went wrong we're going to get a paragraph tag on our page that says hey it's still loading just hang on a minute um but if they're not null we'll get a UL of all the movies and their titles back from tmdb so um I think now is a good time to test it let's see if this works as we expect uh it's pretty slick we can just inject our service here and if I can get titles I know Bobby can get a sweet display for these movies let's see what happens I hope I got my API key in there correctly all right we're loading our web assembly and I will say when the app is deployed that web assembly spinner spins much faster it's able to make some optimizations that it doesn't do and we're debugging just to give us a a faster compiled time but I can see right away beautiful I've got a list of movies a bunch of them popular ones Mission Impossible Etc um I think we got data flowing that's awesome that's awesome all right excellent I think Bobby could take it from here you can make these movies look nice we have the whole object available to us and uh through dot notation it should be pretty easy for him to discover we can even see in our HTML what our movies have movie do popularity it's backdrop pack path what languages it's in um how highly scored it is should be easy for Bobby to use so um I'm going to push this to GitHub and see what he can do with it all right and Bobby are you around for us I'm here beautiful I've got data flowing for you okay cool just pushed it to to get to pull it before you get off real quick all right yeah absolutely if you pull it you should see as soon as the page loads a list of 20 or so movies just right there all the titles for you and if you missed it we gave you a service make it real easy just inject it and should be good to go okay cool all right let me see if I've got it here and I'll let you go then uh I see the models in now okay page cool nice all right all right so um what we can do real quick um I think is just talk about like what I'm going to do next I'm going to actually build the page next and then in you know I'm still in UI land over here so I'm doing the UI I'm standing in for the designer um so but like any good designer I need to wireframe it so let's just see if we can wireframe this guy up and let's see remarkable here okay so let me just share this real quick we're good so this is what we're going to build so right now we have like our layout right here at the top here so this is our you know kind of our menu bar up here and then what I'm going to build is these cards I only want to build one card I want to build a 100 and so what I want to do is build one card and then Loop over them and add them dynamically to the page and so we've already built our nav at the top and nav at the bottom and so now realistically man I mean I just probably need like a header and maybe a card and loopover stuff and it should be pretty easy and what we want to you get out of this section is looking at the power of reusable UI components and then the ease of once you have data coming back and you have objects in your page how easy it is to consume those objects and apply the two-way binding to things so this is kind of what we're going to build so let's get after it here see what we can do all right so this is our um our code here and um let see kind of what we we got going on here so we built a page for us and if I click in here to the home page here I can see where he has his movies running so let's just run it real quick make sure I have the key and um make sure it works I think you put it in global apps settings just so it's easy for us to transfer hope so anyway cool so I've got some stuff going back just some titles and now it's up to us to kind of make this look good so this is the part of this where we're always building apps and a lot of it is UI work let's get to work here so let's look at what UI we have here so let's start ripping this stuff out we don't need this anymore [Music] um we might keep this right here so he's got if no okay so let's just let's work on this all right all right so let's hit the top here um a tab here and then let's add H1 to the top of this page here kind of telling me like hey display one or whatever different [Music] and this the top of our page here and U let's put a little fire tag beside it that'd be kind of cool fire icon again um I've got bootstrap icons available to me and this is why at codr while we install this stuff up front because we know we're going to need stuff like this when we're building things so we just have a really cool um setup that makes coding things pretty easy and when we're building apps I can tell you that we're doing the exact same thing every time we use these things too soste of heart we could say heart but we're going to do fire fire okay so we got a H1 tag up there we've got our Flex column here and what we should add as well to this page is let's put this in a container like the rest of the page let's um so it matches the width of our so container XXL then we'll push it down from the top a little bit and let's just put that around our whole thing here so now I've got this page title we say Blazer movie and we could put you know maybe Goen popular movies just show up in the in our browser heading nothing big deal here all right so we've got this class here which is a flex column and deflex and we're justifying The Columns in the center and a line and all this so I don't necessarily want a column so we're going to put these suckers in a row going to go out to the side here so something like that and space them out horizontally across the page then this is just a the bootstrap style here instead of Center we're going to say between evenly space them in between as it goes cross that let's do this let's add a column back in here so get about our so on mobiles it'll stack everything else tablets it'll stuck it'll go out to the right so we're we're making this Flex box either stack or ground on rows and these are just um bootstrap styles that allow us to get to flexbox through bootstrap okay probably can take this off here so we got us that okay let's get to work in here so now we come down here and um he's got some stuff about the movies here and so what we can do is put a row in here okay right so I think actually we'll do so we'll put some we'll do some cool placeholder stuff here and so we'll put the row on the outside of all of this if statement here because we'll use this row no matter what happens and [Music] um what we'll do is we'll establish a row and to in here all right we'll establish a row and then we're going to make a row like this and then we're going to put either the movies in there with our card or a card of placeholders and we'll show you how our component can morph in both of those I think that would be pretty nice so we'll just set it up to say 2 by two across a mobile and I'm just going to guess here this four maybe five if that doesn't work come back and work on it so it's like two four and five maybe a medium bright point is three I don't know we'll just I think that'll work for now so this is just setting up how we want this to kind of depend on how many um columns we have and we'll just say justify it in the center then we'll then probably on mobile like mediums forward like from tablet to desktop probably want it to the start because these are going to going to be like a row going across at that point so we just side start I am not typing right now so that'll probably do that so that'll be kind of our base set up we may come back and play with it later but basically we have our break point set up it'll be in the center on the mobile everything else it'll start and try to fill them out from left to right not bad okay so we're going to get rid of this UL all together list we're going to put them in hard and we're going to get rid of much this okay um we'll leave this loading here for now so Jacob's got a setup to where we can um Loop over our our movies here okay and then but what we want to do is I want to put in card now what I could do is put the HTML right here but what I'm going to do is build a component and just Loop over and display the component that way the component can be self-contained and over here on my page it looks a lot cleaner I don't have all of this kind of markup going on so I think that'll work pretty well for us okay mov and movie results all right so in here we'll just say div CL class equals and we'll say slash what this will do done how many movies we have that's how many cards we're going to put in there and you can see um copot is trying to tell me to put that in there but I'm going to use a component to do that okay now what I can also do is I'm going to come down here and let's address this we could show movies are still loading or we're going to write a for Loop here and we're going to display 10 placeholder movies and I'm just going to arbitrarily set this to um Z of 10 here so and um sometimes I got the if wrong but it got it right okay so now we've set this up and now we have to do is drop our card and our code here and it should work so let's go over here and let's actually make our card now the reason we're making this as a card is want to show you kind of our the way we're going to structure Pages going forward and you can see here he's already got some folders here model services and we got this components folder here but inside here we have layout and we have Pages I'm going to add a new folder here and we're going to call it UI and I hope that um Microsoft adopts this folder name I like it so but we'll see they do or not I don't know let's rename it I struggle with this but I'm going to do capital I I think it looks better I'm sure there's some other ROM reason not to do it that way but and so in here I'm going to create a new component in here I'm just going to call it movie card this is the card that's going to hold our movie for our homepage we may have some other components before we get done today but I'm just going to call it movie card and that's going to be right here in our um our folder here I'm going to show you one other trick that we can do here is I'm going to come in to my imports razor and you can see here that uh Blazer live and components in layout I'm going to add this um Blazer movie opponent I and I could add models too um or you can put the using statements in each page we only have we're only to have two pages so I just want to show you kind of how this kind of works and what this means is I don't have to [Music] um get that name that's funny that'll work I renamed it let me see here okay we'll keep it we'll keep it like that for now all right so it's thinking this is the name if I build it see if it'll find it it's okay initially I had a lowercase and I changed the name of the folder but it already created the name space I think we're good all right so um in here I've Got U my movie card here and again a movie card component is like anything else it's just got um some code and some um some markup now one thing we're going to do for our movie card is we're going to just do something brand new here in our code thing is I'm going to take this card is g to take a movie in here look at this Co pilot is really good sometimes I know Jacob you're listening but like that's that's pretty good right there um so I'm going to take the popular movie and it doesn't know what this type is so um that's because I had it in include my models in this so I'm going to go back to my imports here and I'm going to include this so I don't have to put that using statement in there and um now when I come back to my moving card it'll it should find it if I do a rebuild should unless that's not in models it is you might have to um you might have to close and reopen the uh editor the window there yeah oh there you go it found it eventually it just took a minute all right so um so right now I've got this I've got a get Setter and I've got a popular movie and I got a parameter coming here now what's important about this is like this parameter is this complex type of this object popular movie and um because I can pass this complex type between components it makes me real easy to build things in a really separated way so I don't really have to know how this gets here I just have to expect it to be there okay um which is pretty good all right so let me show you how I could use this so now I'm just going to rip this out and um let's just work on some HTML here so I'm going to build a div statement here and um I'm going to go ahead and start with an if statement so I'm going to um if and we'll put if popular movie it movie is this is this parameter right here so now um when they push it in here I'm looking to see if you try to instantiate this component without anything all right but if it's not no hey let's do some stuff right so in here I can generate the HTML that I want I'm going to use a bootstrap card for this and um we'll say div and that's card for bootstrap we can make as big as it needs to be because we're going to put this in the container and we want it to fill all the space in the container um and this is another thing in your component design When You're Building Things is look at the container that it's in and style around the container Center and that means that a lot of times we'll go from media queries to like container queries so that our components can truly be module in this case we know what's going to be in so we're going to set it to be 100% tall all right we'll give it a fade in um means one it's displayed then um top of our card remember our UI we looked at has our image at the top and then we're have the information on the bottom so I need to put our image in here okay but sometimes for some movies what we've learned is that sometimes they don't have a poster which you're like what movie doesn't have a poster one that hasn't been released yet but somehow they're in TV um somehow they're in here so um so let's check see if our poster is null or empty and um we can look at this check this out I can just say movie do spell it right poster path and I hope that's not lost on you like super powerful like um I don't have to know about the API at this point have to know anything about it it just finds it all right and so I'm not going to take any of this because me Smalls hit the key all right so I'm going to just put an image in here and I'm going to give it a class I do know the class is from bootst because I made a bunch of cards in here but it's like image top that just gives it a class and sets it on top and we can say alt we give it an alterate name movie poster and then we just give it a source equals and check this out we can we're going to give it this is saying let me check my code here if string is null or empty oh if it's null okay yeah so I want to put this images SL placeholder so we made this image called poster placeholder just in case this doesn't they don't have one we fix it up we've used this in the past and sometimes no data shows up okay so now okay we'll take it co-pilot and we'll look at it all right so same thing here so we're having an alternate image tags depending on the value in that object that we have um we can write the HTML that we want movie poster then okay I think that is right okay cool um I thought I was have to explain this but basically here I've got some razor code here and then inside these these parentheses here um I've got this if you're used to JavaScript this is like a temperate literal where I have a dollar sign and then now here I have this string literal right here which is the base pass the all images inside of um the movie API and then here I'm pulling in the path from the API call or really the path from the the instance of the object that was sent to this component and so that's how we're going to resolve our images so that should work okay cool all right so we've got our card top and then in here now we need to do our body we'll say class equals and it's I think it's card Dash body then um we'll give it a border dashtop and and make it background we'll just use a bootstrap background now you could color this how you want we could use our themes or whatever um so I'll take this again from co-pilot copilot's helping me out so this is the card title and then at movie title and then at movie overview okay but we're not going to do that we're not going to use the overview even though it's being passed in only thing we want here here is the title and maybe like the release date and so I'm going to come in here and say class equals card- text and then from here I want to display a daytime in a certain format and again this is another thing that's kind of cool because we have access to a of.net we can call things like datetime parse Che it out man all right so um it's saying this release date right here it tries to parse it and if it does it formats it and that means if it's not a date time it's not going to format it in this format so don't have this problems you have sometimes in JavaScript you apply format the thing and the date and the data is kind of wrong because you don't know if the data is right or not so this is testing it and then trying to format it um and because of its type we know that it's going to be format correctly all right so that's kind of cool so we got our card body here almost done here and then one of the tricks that I do I'm building out cards with the bootstrap card system is I always put a footer on it and there's a reason I do because it makes this line on the bottom then if you have um height of cards that are different in the body the foot will make all those visually aligned together regardless of how tall this content is sometimes you'll get these cards that are small and some are taller but if you have a footer on them they'll all visually line on the bottom it's just a trick that I do um we'll make sure this is at the end and I'll put my button in the footer okay and so we're going to say class equals n n- primary then here need a hre okay now we don't what this button's going to do is take us to the detail page but we don't quite have that yet so we'll have to do that in another session we come back we'll come back and maybe fix this later okay um because we don't really have it yet so um we'll wire that up later okay so that's our c all right so now if it is null check this out watch this now hopefully what you'll see happen here is you'll be able to see the placeholder and then watch him come in and you'll probably think oh that's magic and it kind of is kind of is so I'm going to make another class here and we're going to say card right and um we're going to say 100 and I was hoping it would help me but it didn't now it decides not to help me that's okay so we're going to say class equals image and then we'll say art equals movie poster and Source equals images we have a poster place order right here so on the top and then we just need a class equals pretty much the same thing we just did but we're not going to have any data in this one this is just simply to be placeholder text and what this does is take your project to I think that next little level to where you have placeholder day instead of just a logo spanning or like hey stuff's loading be right back um this takes it to that next level okay now it knows what I'm doing I think it's listening to me Jacob so we in bootstrap have these classes we can say blaz holder Dash glow and they'll kind of pulsate here and this is built in the bootstrap so it's kind of cool you could build a similar thing with anything else that you want okay and right here this will simulate our title okay then in here in our CeX same kind of thing here we'll put our placeholder [Music] glow and then in [Music] here I was hoping it would load it for me but it didn't that's okay get used to it giving you stuff and it doesn't you get mad at it where are you co- pilot and we'll probably put a footer on it just like we did the last one one more dip here and we'll say Mass equals card footer and text Dash end we'll say button what we'll do is we'll put a fake button on this to as well cool else and what I'm going to do here is just hit the same thing BTM primary then but I can say disabled I don't try to click on it and I'll say placeholder this will style it where it looks like a placeholder I think this will work I have problems come back and change it I don't know hopefully it works just a heads up for you yeah yeah I see that right okay I gonna say auto complete did the same thing to me earlier yeah that's that's the co-pilot button so co-pilot special yeah it dark buttons it really wants you to put them dark okay okay let's see if it works and um hopefully this works all right so let's check it out so let's add it back into our um our page here so I'm going go back to our homepage here and where I was coding and um because I've got my uis loaded into my Imports I should be able to find it now so it's going to say movie card this is going to say is not null okay and I'm going to hopefully Enlighten you to something really cool here in a second you haven't seen this before so I've got movie cards coming in here and so but if you paid attention I've got a pass the the current movie to this instance of the card and check this out to make parameters work I just say parameter over inside of my um my markup and my component and it's going to know about it find it here I call it popular movie should find it not what did I call it or did I call it movie it it was at the top it was movie okay the very top there it is okay I'm looking for it an alphabetical order all right so now it's got it and what I do here is pass it the instance of the movie that I want this one to render which is this variable right here and quotes in here and um you put it in quotes just like you would anything else but if it makes it light blue you know that it oh I know what instance that is in fact if you Mouse over it it says oh this is a local variable of type popular movie okay it's going to pass the movie and all of its Associated properties into this component now on the flip side this one down here I didn't pass it anything so therefore my movie coming in will be null and if we go back and look at this I'm checking to see if this is null or empty and if it's um is null or empty I've done this did I do it backwards oh yeah if it's null or empty um right here at the top it says if the movie is not null show the data and then it comes down here and says the else statement and says oh if it is null then just use this placeholder content and that's because I didn't pass it a value this parameter wasn't satisfied and I said hey this can't be no that's what this question mark means and um and I check it over here so let's check it out and this is the power of components the power of 2-a binding and everything all roll up into one that makes building these things a cinch and hopefully it works now did you see that so if I I could slow it down but like um this needs some work right here obviously that needs some work let's fix that that's going to bother me jackob all right so let's go back to our page and let's just okay so H1 is not block I guess so actually it's just in the wrong spot outside here I think going be much better did it work did copilot actually work I let's just try one more time I don't think it did NOP blew up we're hoping that um the kind of inconsistencies with hot reload will be fixed tomorrow when the new version comes out okay so now we got popular movies at the top here and if you looked real close I refresh it you'll see when it's coming in here the placeholders will come in right there and then it updates and comes in now for those of you that um and it's like so what I want you to think about what happened here it it basically said if this is not null run over these cards if it is null run over these cards and so when this task took like two or three seconds or whatever to go out to the internet movies for a minute is null and so when it loaded it ran this for Loop and then suddenly this comes back from this async task that just happens to complete and it goes oh you're complete now oh okay rerun this for each Loop now and boom our card shows up now notice um and this is the power Blazer we didn't have to wire this up we don't have to like do some kind of check change state or check state or build some other kind of stuff if this is that and we just make a basically return this get a variable back and if this variable State changes Blazer will update the UI in about in most cases and in the cases that it can't there's other things that you can do but for the most part this is the magic about Blazer and that's why I always tell people like okay the render modes are cool but the moment you start building with components and two-way binding you're hooked immediately because that is the power of this this is like the sizzle is that render mode stuff that we're seeing the stake is building this stuff with components and then um really building these responsive uis now let's do one other kind of cool thing that we can do with this and let's go back to this component here and um let's s for imagine that I wanted to use a third-party JavaScript library and a lot of people think oh my gosh this is like impossible to do inside a Blazer it's really hard and because it's hard I want a DOT Blazer and I'm going to show you that it's not that bad all right so if we want to call Laser we can inject um the ISJ runtime right inside of this or the ijs runtime right inside it and what this allows us to do and we use the word JS you can say JS run time whatever you want we use the the word JS what this allows to do is to call third party um JavaScript libraries because if you can imagine in web assembly I'm down inside a web assembly I really don't have access to JavaScript so so I have to call back out to make it do things all right um so that's what I'm going to do so Jacob I believe loaded in if I go back here and look in JS this vanilla tilt um JS which is basically if you have Mouse over it it kind of makes things kind of move around it's kind of cool so I thought why don't we make our cards kind of tilt okay and so this card the not null card we want this to tilt and so the first thing I've got to do is I've got to get a handle to this element in here now in JavaScript we would say hey just put an ID on it and do something like get element by ID but how do I get to reference this element inside of Blazer and this is how you do it so down here we're going to create another variable called um element reference okay and this is a private variable and I will we call it element reference and um we're you can name it whatever you want but I'm going to call it poster card element and I can call it whatever I want to call it it doesn't matter as long as it's of this type here so what this is going to do is actually create an ID on this element that we're looking for so that we can reference it through JavaScript and so I'm going to come in here and come in here and and use a c method laser syntax and at ref and then at ref equals and I got to give it a name and I've got to say the same name I called this in here so I'm going to call that and put this did I put it on the wrong one I did make sure I put it on the one that I want to work on notice too I didn't have to really have to copy it it just found it for me because it's declared in this um code block so it knows that there's an there's an element that I can put in here and if I Mouse over it you can see it's called field movie card poster element so it knows what it is all right so now I have a hook that now I can do some stuff with okay so inside this code block I also have the entire event life cycle just like we do on pages on render and everything else so every component has its own life cycle which is good there's a lot of events that you can look into and so today we're just going to use one of these and um the one I want to look at is override this is going to be after everything is rendered and it's going to be on after render async thought it would do it yeah there it is all right so on after render async happens after the entire page has been rendered and all the elements are pressed or all the elements are are present and so once that happen happens I want to be able to um do some stuff with it you also have this bullion here that says hey on this um first render do some stuff here now notice here that um it thought I wanted to invoke JavaScript which I do just not this JavaScript you so which is okay but um here right here when you want to vote JavaScript is the name of the function that you want to call okay and you just have to know your library so I know this is called vanilla tilt this is in their docs a knit I just know that got to spell it right so if you had another JavaScript library and it had a different AIT function or it had a method you want to call you'd have to know the name of it you put it in quotes here and then um for this one I want to pass it Mr card element then because I know how this works this a nit function takes an element and then it also I can pass it some values and this is all based on vanilla ENT this is nothing to do with blazer this is the JavaScript library so if you're coding JavaScript you've probably seen stuff like this where you got to pass it an object to init it and so what I'm going to do is give it a speed of 300 and a Max tilt of 15 so it's like like this and and it's just a setup that we can do [Music] um so I'm calling the function I'm passing the element and I'm passing the object and this is probably because this is all really JavaScript but I'm I'm invoking it from my c pretty simple and then I'm going to call a dispose because [Music] um what we should do and then what they said we should do and let's see here I think this is right we'll just run if I get an error we'll see all right so we'll see what happens here so now I've got this saved I changed my component I'm going to run it and hopefully I'm hand this back to Jacob with some cool like tilty action or it's going to blow up and you have to rescue me again we don't know what's going to happen all right here's the magic look at that it actually worked Jacob it worked all right you mean we can run JavaScript in our HTML Pages we can and um I got a little problem here like I want to fix one more thing before I hand it to you like these are a little tight so I could probably hit the grid up here um so I'm going to go to my page here and maybe just three maybe what you think too big three is my favorite bootstrap number it's always my starting point so I don't know so this is not null yeah I don't know let's just try it so maybe that'll save I I don't I don't think it'll save for me let's try to Hot Load it usually for me I get one little check here and I get one shot at it there we go now we got a it's a little better cool cool nice all right so um I think I'm done here um I'm going to push um what session we in four okay yeah it's four [Music] go that we'll just commit it to master just to origin and I'm out all right I'll pull those changes see if they work um I do want to just point out to anybody watching that I think it it's easy to gloss over what we just did with those movie cards um those of you whove written a lot of JavaScript just just think about all the code involved of hey I got this card I'm gonna bind a new object to it I'm going to replace what's already there I'm G to put it on the page you know that's like hundreds of lines of JavaScript that we don't even have to think about no we just have an if statement yeah then you add in the complexity of doing placeholders so I have two types of compon components you know like or two states of the same component it's a placeholder it's not a placeholder is it null is it not null and then it comes back and goes a I'll just figure all that out for you don't worry about it Bobby I got you Laser's got you it'll just change it we're good you know is it cheating a code I don't know I don't know if you like technology it's not cheating so look if it makes me building that faster I'm good yeah it's pretty slick okay all right so um next let's um I didn't wire up the details button okay so you might have to do that and make a Details page I didn't do that so if you want me to do that I could go make one real quick but you think you got that no I got that let's make a Bare Bones one and then uh I'll come back and sty it okay that works for me all right all right then let me sure let me pull my screen up and let's see I've taken a look here sweet so all our changes come through we got our cool tilt love that um but our details button does nothing yet okay all right we can do that this is pretty cool um so we briefly touched a little bit on routing in Blazer I think um we can see on our homepage oh my visual studi got to catch up um we have this at page at the top that we haven't talked a whole lot about currently um but what this does this is this is the really easy answer Blazer has to routing I know in other Frameworks routing can be pretty complex subject lots of choices to be made um and Blazer it's pretty easy you say at page and what you want the route of this page to be and if you don't put an that page well then you just have a component that is not routable but can be put in other Pages um which is awesome so up next we need to make ourselves a Details page so we'll go ahead and do that I'm going to add it to our Pages folder I'm going to go ahead and add a new item this one we'll call uh what movie details or we'll just call it movie. raiser um so this will be the detailed page of a movie and we're going to go ahead and give ourselves a route we're going to say it's going to be at page um uhoh there we go all right at page we're going to call it slovie if I can type in the right box and uh what's really cool about these routes is that we can not only have just a a string route slov will take me to this page um but if I want to see a particular movie I need to know which one I need an ID and uh makes it really easy in Blazer to have what we call route parameters it's already trying to suggest it to me um if you've ever built a web API in net this should feel pretty familiar I can put these curly brackets here and whatever comes here in the route after movie and the where the ID is will be bound to parameter for me named ID um and what's even cooler about it is I can say this ID needs to be a particular type not just anything if I get a string in here that's going to be a problem for me uh our popular movies have a yeah an integer ID so we can add a constraint here we can say uh this page is routed through slovie an ID and it must be of type int which is awesome um and because of the Blazer magic I can just add myself just what copilot suggesting a parameter we call a route parameter named ID um so just like components we can pass parameters when we put them into our markup uh on a page component we can also add to our our route a route parameter really easily just as easy as any other route we put in here which is awesome um so for now we're going to go ahead and just put in a P tag that says our movie ID is and because this is a property of our page we can access it through our razor syntax really easily we're going to say movie ID is at ID um and this will give me these a good starting point to make sure my routing Works once I see that once I know that that's working we're going to go ahead and write our code to get the details of a particular movie um but let's just make sure this routing Works um I'm going to take a look at our movie card component because I know that's where our page is or our page our button is for the movie oh Visual Studio is upset with me but that's okay it's probably just catching up to the latest changes let's do a clean and rebuild and hopefully that'll help all right better well maybe not um we'll take a look at this button here I know this is our details button currently routing back to our homepage I want to route to slovie slash and in this part of the route we need to put our ID and that's as easy as getting our local movie movie dot ID boom we're good to go with that one uh no I'm not missing using directive so we access that property on our movie model the ID so that when we do go to that movie d Tails page we get that ID here in our route when I click that it should take me here movie SL2 500 whatever the movie is when our page loads I should see the ID um so let's give it a quick test let's take a look see and see if this works like I like I'm promising you it will and if that works we'll be well on our way to get a movie a detailed page about our movies that is all right we got our movies listed here we'll take a look at Mission Impossible and nice movie ID is 575 264 I can see that's up in my route or in my URL as well it's exactly where that's coming from which is awesome let's try with a different one make sure we get a different ID we do 678 512 and one more to be save 299 054 sweet so all these movies are taking us to a different uh ID the link is the ID of the movie which means we'll be able to use that in our component which really means for me we'll be able to use that in our service method to get details of a movie so we're well on our way that's awesome and if for those of you who who have written um apps and other Frameworks things like um angular react view whatever the case um you know that passing these kind of parameters like a route parameter can be uh a lot more code sometimes a pain to set up um but here it's as easy as putting in our page route and saying oh by the way I need a parameter and put that in curly brackets um awesome so let's take a look at our details call now so we can get the information we need our movies our popular movies page um or endpoint does give us a lot of information in a movie or about a movie frankly but uh this details endpoint is going to give us even more details that we can show to our users um and hopefully Bobby can style it up pretty sweet so as I take a look here this is the details page I knew this was coming so I pulled it up up for us um we can take a look at what this response is going to look like um and it's going to have many of the same properties we saw in the popular movies endpoint um backdrop path belongs to collection some new information like a budget an array of objects the genres are homepage another array of objects production companies another array of objects countries okay so this endpoint is looking like it's going to take us a few models um but luckily just like last time we have multi cursor to help us out we got pasted Json to help us out let's see if we can do it quick um any good IPI documentation will give you some example Json that you can use um and tmdb is no exception so I'm G to grab that Json here head back to our Visual Studio and let's make ourselves a class for this we're going to make ourselves a movie details class and to give oursel a quick shortcut Head Start we'll go ahead and paste his Json or paste Json as class paste special Json as classes boom and hey that was pretty good we got our these are all of our arrays of objects uh spoken languages production countries production companies genre that's awesome and our root object which is going to be our movie details so let's get rid of that let's see yep that's good and now we got curly bracket okay so I got a movie details we're going to have to change all these to our C naming convention we can probably do that pretty quick I think um let me rename these classes not production uncore companies but production companies Pascal case not production uncore countries just production oh just production countries and get rid of this underscore as well boom and let's see how fearlessly I can use multic cursor this time because um for anyone just joining who didn't see it before uh in C our naming conventions do have meetings to us as developers and properties should be Pascal case capitalized uh and these are all snake cased so I'm going to see if we can change that for ourselves pretty quickly all right I will copy that and we'll do ourselves a Json property name of whatever the heck I copied all right sweet we'll make sure those are all right when we get to it um we'll add our using statement here and sweet now we just got to rename these guys nicely oops backdrop path and that might be no oh belongs to collection is telling me he's an object I don't think that that's right belongs to collection is a string oh a nullable string to be precise okay belongs to to collection budget easy fix genas fix our name violation make it an empty array oh with is semic calling homepage homage one word id imtp id language get rid of our warnings here overview popularity production companies production countries status [Applause] [Applause] tline we've almost made it just a couple small class names to fix and we'll be in good shape [Applause] oops and [Applause] okay I think we've done it I'll tell you anytime we use um an API guy that this edit paste special Jason's classes is a lifesaver that's going to save me from having to type all this out manually um and I think all these types are okay let's just do a quick check strings are fine an array is okay for these things oops um it is a good practice most of the time if you have a collection property something like an array like we have here a list something like that to initialize it to something empty to avoid null reference errors just in case there is no value for it um you could make it nullable to be clear that it may be null um but I do think in most cases an empty collection is probably more accurate for what it represents than a null list if there's no value then it's just an empty list um but I think an array will do fine for for how we're using these all right awesome now that our data is modeled let me go ahead and grab this URL here um tmdb wants us to go to movieovie ID hey that's the same Rod I used um so let's go to our service our tmdb client well we're already configured to use our API key we already made it work one time popular movie page response beautiful let's do another one public task of uh what movie details is what we called it might be null might not get a response out of our control and we'll say get movie details as we'll call it and we are going to need an integer ID and just like before we're going to make a call uh using our HTTP client going to get from Json my favorite shortcut um in that it gets the response attemps to parses Json returns to the object which is the same thing I'm going to do to every API call I ever make so well 90% of them um and it needs a route a URL which is going to be movie slov ID so we can use our template literals and use our parameter we'll give in an ID we'll go get that movie and we'll return the result of our fetch parses Json turned into this object return that object and I think that's all we need since we're already using our base URL api.org sl3 beautiful beautiful beautiful all right let's head on over to movie oh the movie page not the class the movie page um this HTTP client's super powerful if you guys have called an API in JavaScript you know the pain of either putting it into typescript and hoping it gets correct and coing it or using vanilla JavaScript and hoping you type the property names right this will parse it make sure it's the right type and give us an exception of not which is great um and because it's part of my service I can head on over to my movie page I can inject that service with just an easy at inject my tmdb client uh we'll call it tmdb and you know I don't want to add a using statement let's update the Imports at using please me this live Services um I'm not sure how much we talked about it before but this imports. Riser is a super powerful file and that it will automatically bring all of the using statements in here to all of your razor components which can really save you on those lengthy using statements you sometimes get in classes or um for things you're using all the time really saves you time of of going back and adding your using statement so that should fix it for Me Maybe maybe my Razor markup didn't catch up PB client yep okay let's go ahead and see because it builds fine let's see if we can use it and hope Visual Studio catches up um so just like before co-pilot predicting my thoughts um we are going to use our Auto initialized async method this is what's going to run before our page renders it's going to go get the movie that we want um and then assign it to a variable for ourselves um but I actually want to make that not a local variable but a a uh field or property of this page um so we'll go ahead and add that real quick we'll go ahead and make it our private so some one else has to see it movie details it is nullable we call it movie details because it's a private field we can use camel case we'll use that as our response or will assign our response to that guy get movie details a sync I see um looks like visual to cup to me get movie details ID and I didn't name it async but I should so I'm G to go fix that because this does happen [Music] asynchronously all right sweet and it's going to be our ID pass in as a route parameter like we said easy easy got to R parameter when our component begins to to render or or run initialize itself it'll begin this process of fetching our movie details when they are fetched it'll be updated on our page so we can say at if uh movie details is null we'll just say loading for now else we don't need this movie ID let's see if we can do a H1 with the movie details title and the movie details overview just to make sure this works for ourselves uh and again that's the beauty we didn't write any code to update the Dom um which is probably about 80% of the JavaScript code that I end up writing all I did was I said okay go ahead and get some movie details whenever you got them well wait whenever you got them assign them to this field and now my Razor markup my my pages code is saying okay if movie details is null if I don't get anything back or it hasn't finished loading yet show this otherwise show some information from that movie details response if it's not null um and I don't have to write any code for that to happen laser just says oh this has changed your view cares about what is in this local variable this field uh so therefore I'll render the part that cares about that um so let's test it out let's see if it works made sure it's not null then access the properties let's see what we get back okay let's go check out uh Mission Impossible uhoh something went wrong we didn't get the response we thought we would let's see belongs to collection could not be converted to a string h well let's take a look uh what did we expect to see and what did we get belongs to collection ah it is an object but our example Json didn't give it to us um so I know that's probably small for you guys but I could see in my developer tools that Json I got back and the example tmdb gave me had null and belongs to collection but instead there's a Json object so um let's go ahead and make that let's see if we can uh model that correctly and then you know go about our day that is one of the things that I appreciate anyways of our HTTP client is that it will tell you if our response was not typed correctly um so let's see belongs to collection so let's make a new class here we'll paste this as Json maybe not belongs to collection okay okay tmdb you giv me mixed signals here okay let's paste that as special we'll call it a collection on property dat all right we need name these guys real quick and that was our belongs to collection that is a uh collection object the one I just made up that I should probably actually rename I think C uses that name elsewhere call it a move collection all right let's give it another shot even though tmdb told me it was a string it wasn't so let's see what happens can Mission imp possible I'm coming right back for you beautiful the fact that we made it to this page and we got a uh movie details object uh tells me that it parched correctly it was um it matched our our class so we have all the details in here um shown up on the page let's try some other movies just to see uh Oppenheimer that's a popular one right now sweet and Marvel's I know Bob's going to see that tonight he's it's on his urgent to watch list um and that comes back too sweet okay I think we got our movie details in there yeah we got it along the way I think we got it I think so can read about fastex now you know not my best work on a front end style but I think we got our details we can make it better I think I think so I think so functionally mission accomplished but uh we can make it pro what is this session five all right Bobby so I've routed to that page with the ID I got us the details uh endpoint um and I've showed a little bit of the details in Ed the service for you so you can at least see details are coming back uh and I think I think that's it I think it's back to you okay see if we can get latest here and I'll say everything's modeled out strongly typed in the classes so should be easy for you to see what what properties are available to you there okay let me look here make sure I got it movie details object that's it it's got a few classes in there but they're all nested together it's a lot the they' kind a lot yep okay um so now we've got to do um to build out the most complicated page that we've had so you're still with us this is going to take a minute it looks cool but let me just uh share it with you show you kind of what we're going to build here um so we've got our menu layout and we've we've got this detail page that we want to show and so the main thing that we want to be able to do is in here like right here this is going to be like a poster backdrop that we're going to pull in to put it on the page and then we also we'll probably bring in some other data like in here maybe like the release date some other data I come up with maybe some links to the IMDb page or whatever but the cool part of this whole thing is we want to take this poster and hang it off the edge there of our backdrop so that would be the hard part what we're going to do from the CSS um and while moving the poster is easy it's just then once you move it you got to move everything else so it's going to take us a little bit of CSS to do not as much Blazer more CSS and a multiple break points so we're gonna have to put some media queries inside this component to actually get to work on all of them so we'll try to get through all of that and then we'll come back and see what else we can do to this so we're going to be here till we finish so um if you're watching this in the future get ready for some bootstrap and CSS I guess so let's see what we can get into here um so this is um let's look at see what we've got here always like running after I get it to make sure I've got it and um so Jacob has put in this class in the service for us and so now let's see kind of what it runs and see what the state of the union is so we got a page here and now we've got a page here but we want to like take this overview put on the page get the poster get a backdrop going get the title kind of styled up and then make it work on all three or four break points mobile get it working on a tablet maybe a tablet landscape and then desktop and Beyond okay so let's get to work here so it should be a lot to do now the thing that's kind of cool about this is if I come over here to this movie page here this is all done for me so like this is kind of what I need I mean I got the details and I need to just load it up in here so it's um at this point now it's just styling and laying this out and hopefully that's not lost on you that this is pretty easy to do okay all right so um we'll keep this loading um loading the movie something like that we'll keep this in place place here we'll keep it up there um like we have it we could style this out and do some other stuff like I did before but um instead of putting a placeholder whole visually thing we'll just do it here just know that if I was pushing the sound of production I'd put a placeholder front end together but so some six so let's get this done so I'm sure Jacob wants to eat dinner sometime tonight all right so um let's add a let's take this out don't need this anymore and um let's put our page title inside of our if statement because don't have one if it's null details do check it out title so when you when you have all of this stuff modeled out and you've got all of these objects coming in it makes it really easy to um build these things out so I am going to ignore our buddy co-pilot because they have no idea what I'm getting ready to do okay so what we're going to do is first off off we're going to set up our page Banner so we're going to do this in steps so you can kind of see what we're doing at the end of the day this is going to end up being a lot of um HTML so let's start off with our div here and our div is our bigger page and um inside here I'm going to give this a class and we're going to call this hero BG like of a better name and I'm going to do this kind of trick here so let me show you how this works so um if you go back and look at CSS and you're looking at CSS vanilla so we can go back here our map our app CSS here and you can see here inside this route we're setting these variables equal to a value and we do that trick and then we can reuse that variable anywhere we want and it pulls out this value and that's the the great thing about CSS variables well what I'm going to do now is do this same kind of trick but I'm going to do it on an element in an inline style all right and there's a reason that I'm using inline style for this is because I want this component to modify this style here and um so just say at me do a little razor code here and um in here I'm going to also do our temperate L I call it temporate Lal I think it's called something else actually in C but it's the same thing um so we have a dollar sign and now we can put variables inside of this but what I'm going to do is I'm going to say is Dash dbg Das image because what I want to do is set the background image of this div and I'm gonna control this from an isolated stylesheet on the back end of this component and so I can set a value of a variable equal to something and then it'll set its value and turn into the Styles sheet so um it's going to be a URL here and inside this actually inside here we can say https and we got to know how to get images so I'm going to just type this up and sb.org slash T SL P SL original for backdrops the other ones are like 500 and 750 this is just original this is like and there's different paths for different types but we're going to use the original backdrop for this and tmdb kind of like creates these for us and then in here now drop in and a variable this is why I did it on the front end because I can say movie details do so to see how this would work we've got to set up our um casing sty sheet or our casing sty sheet on the back end of this so let's go back in here and let's add a stylesheet to this movie page here so now I can say add new item it's going to be a stylesheet and I'll move this over so you can see again we got to name it the same so we'll say movie razor CSS if I did it right it's going to show up here okay and so now this is where we're going to do a lot of our work in this isolated stylesheet and this is what I I'm kind of really digging about I say stylesheets is before I would either create a separate stylesheet just for this or I would end up with a 10,000 line CSS style and while you can say control find it becomes kind of unwieldy in one file and here we can go look at this page and see the styles that apply to this page now I name that style that I just created a hero background and the reason I called it hero is the old school of like um used to be called Heroes but it's really just a background and um we want to set the background image of this div I'm going to say background image and then I can say watch this D dbg Das image I'm dynamically setting that variable that I created in the inline Style just like I would if it was in the root and if you didn't know you you could do that now you do kind of cool and they just got to be spelled the same I'm just double checking to make sure I spelled it right okay and I did all right so if it's not working now now that I have this background image instead of putting all of this code you're probably think why don't you just make an inline style could have but I'd have to have this really long string in that style and now I just want the only thing I needed was that image and now from back here I can set these other styles that I want to do it's a little bit cleaner to put it in the stylesheet back here instead of putting everything in the endline style but um this is a good use for inline Styles and um we're going to background position this to cover and then we'll see if it's going to background repeat it I'm you're waiting on to help you and sometimes it does and sometimes it doesn't then we're going to arbitrarily set this Min height to 400 pixels so we want it not full page kind of halfish and um we just made up this number so there nothing special about it we just know kind of how big we want it to be so it' be like this tall so you can um play with this you can make it full screen screen if you want a full screen backdrop whatever you want to do but we're going to make it like half screen and then move that poster down make it kind of cool effect like it's hanging off the edge of it so a little overlapping okay so we' got our style here and we've got it set up so let's work on this a little bit more so I've got this hero background this will drop an image in here and boom set it to 400 pixels and then in here I'm going to make another class here and this is going to be what we're going to call the movie container and there's a reason we're doing this too because what we want to do is [Music] um is we want to blur this background okay and so we're going to create a div here that we can set values on that impact its parent so we got this background of an image image that'll be sharpen and focus and then we want to use some CSS here to blur that background so it's kind of it doesn't um dominate our text that we're going to write on top of it in here so if we go back to our Styles sheet here we can um add in a new style here I think I call it a hero container hero we'll check that just to make sure that's what I called it sometimes I spell things wrong and you can look at it especially going live if as as earlier you're looking at stuff forever and you're like it's just a pound sign okay I'll never live it down so we're going to set this one to match the height of the element before for it so just make sure that if you're trying to do this at home know that these two things are kind of in sync and this is just a layer over that but because of the way backdrop filters work it has to be a child layer to set it you can't set it directly on the other layer okay so we're going to say width um 100% height is 100% And so it'll be directly positioned over this and so we'll say position is relative Lo relative then um we're going to do our little backdrop filter here so we're going to set back drop filter there we go and we're going to filter blur it and you can play with this if you want to um pixel seem to work you could make it two if you want it super blurry we'll make it two and then we're going to Dole it down we hit brightness and we'll make it 50% less bright um if you don't like this if it's too blurry or if it's too dark or not light enough you can you can change these then [Music] um margin bottom on this and we'll make it two rims so that may know push this down and then a little two rows underneath it so we'll make it blurry okay should work cool no error so far all right so now um let's go back to our page and see what other things we can do to it if we can get some some data in here so it's really start working on a little bit so the next thing I want to do is I've got my background and I've got my effect on the background the Blurred container and now I'm going to make another div and this is going to be actual data that I want to put in here and this container is again we're going to be XXL so everything else um movie content goes here everything's going to flow into this container and everything else around it is to like make an edge to edge background blur it and now let's put our actual titles and maybe the poster path things like that okay okay so we've got two sides to this we got a poster on one side and then the other side we've got our title okay so what we're going to do is here we're going to use flex box for this so I'm going to D Flex this column here and everything under it going to be flexed and then we're going to say be a column on mobile up and down and then in [Music] um tablets and above row side to side so we'll put a poster on the left and our detail title on the right and then we'll stack them over top each other on mobile that's kind of our base setup here and if you come to codr you'll know that we do a lot of this kind of layout with Pages a lot and this becomes old hat after a while that uh you start thinking in terms of columns and rows and that's how my mind I have it and you also as I showed you my it's a really good idea to draw these things out beforehand and that way you can sort of plan out your columns and your rows and how it's going to lay out makes a lot easier to do instead of just start typing okay so in here let's make a div here this is our first div and we're gonna um this is going to be our title okay so um let's just change this title content and this will just be the title to the movie and then we'll put the poster right under it okay and then in here we're going to say let this one grow okay so make this title as wide as it can be and then shrink it around the poster because this has more text things like that and inside of here we're going to flex inside of here as well and this is where we're going to have a title and all these types of things and so allowing us to flexus allows us to align the items in here Center then we'll justify content and we'll end it actually Center it and then on the bigger ones make sense so we get some content in there so that's looking pretty good so basically um and now I want to lay up my title in here so I'm going to make a div another div okay and this is we'll give this a class we'll just call this title- container now notice what I'm doing here is I named them all the same so I had hero background hero container title container little Dash it's just a naming convention I followed for this component and uh seems to work pretty good okay and then we'll a mobile will'll center it or else we'll shove it to the end okay so I'm going to try to put an H1 in here and we'll start with here we'll say text Das here watch this M details do here there it is okay no I didn't have to know anything about the endpoint I don't even have to know anything about TMD itself Jacob did all that work and that's kind of cool and then I'm going to stack another H2 in here um sure it's light as well we could have classed these in our own class and set it to our style but I think white works really well because we know that our background is going to be dark and [Music] um details dotline boom cool then um stop there um let's see kind of what we got we don't have our poster yet but let's just see if we if this is working should work see I don't know there we go so now I've got that blurred poster back there and I've got Mission Impossible de rening part one um in our testing we use the reason we're using this movie is because it has like the longest movie name ever and then this is the uh we all share the same fate you notice it's bringing my font in because we we uh fonted those up um in the very beginning in our root style sheet um we could change this we want I'm going to leave it like it is okay so let's put some more information in here we could put maybe the release date um maybe the run time maybe some votings like there's you know it gives you stars and that's based on people who voted for it um so see what we can do there and see if we can get some more information out of this details to add it to the page okay so here I'm going to continue to work inside of this div because this is our container and that reason we wrapped it is because this container can move around like a box inside of this one half of this page and that's why we wrapped it so I'm going to put all of my stuff inside of here first thing I want to do is figure out if it has a release date so I can write an if statement and you've seen me look at release date before um and how we did it before we're going to do the same thing again net for the win here we have um datetime parse and we can say trap horse and uh we just give it movie dot release date okay cool then here we have an out parameter see what I'm going to do with this in a second it's kind of neat time and we'll call it release date so what this is going to do is going to try and parse this Rel release date and if it does it sticks it in this variable and then I'm going to use this variable okay if it doesn't parse it this will be null and this line of code won't run so it'll just remove this line of code and that's why I'm putting it on its own line here so I'm going to say span and we try to make a badge here this badge comes from bootstrap here and me2 spread it out and we'll give it a background just using the stuff in here and I can say at I can use that out variable on this if statement here so it's a really powerful feature and more advanced in what we're doing here but uh it's kind of cool I mean like when you're bringing in all of.net and you have all the features it makes building your uis this would be a problem with JavaScript otherwise you know you have to write some other code or whatever and I'm not really having to do a lot of codes like really kind of easy then I can just pass in um re doing all day which is MM Ed ww and that's our um how we want to have like month day year for it okay so that is daytime for the release date then it's oh it's trying to do runtime for me so if I don't want to do that I could but um that's not very good so I'm going to acculate the run time because I want hours and time and stuff like that here that's going to equal and I'm going to little math problem look at this Cod already did it for me runtime divided by 60 um and then the mod 60 gives me hours of minutes propilot for the win right so uh I'll just keep that okay and then I'm going to get a rating here same thing here close but I'm I'm going to multiply it by 10 because I know what the number is coming back so this is a a percentage coming back multiply it by 10 instead of saying 74 I'll get 74% that and I can do something like two string maybe yeah all right let's do this a different way that was wrong and let's do it like this and try think that'll work check it out here in a second all right so um I need to put this in a an ad statement that's why it's not compiling razor code there we go now we're cooking I've calculated a couple of variables just like I would in C and now yeah my badge yeah look at that co-pilot it again thank you I'll take it all right so what I'll do is I'll give these different colors dark and maybe um this will be success of the rating can be green like that then um I I think I could put some Stars beside this so like 74 Stars I think that's kind of like they give it rank I don't know so I'll just put an icon here class equals the I have to do this I don't know if this will look good or not not but we'll see know there's some Stars inside of an icon here so we'll put it in there by that okay so one more thing that we could put in here is um detail stat there's no movie detail stat see that's where it's just kind of wrong um what I can do here is I'm going to put some um some links like the IMDb page and its website in here so I'm G to have and I'm make another div in here and I'll say class I know I probably have to style this so I'm going to go and make one don't use it it then inside of here here um I'm going to put a link side by side maybe some buttons or something I don't know we'll see make this up here and then umy content Center then MD end all right so that's going to push it to the end on tablets Center this in in the middle here maybe put a little iding around it what happens if it's got a homepage so we'll say if um I use the not sign there is no or empty if it's not then um we'll say movie details do it's homepage yes homepage yeah the homepage is the homepage that the movie has a website and it'll be in here and if it is just put a div in here and [Music] um I'll take it because I don't feel like typing anymore and let's see here I'll change it so I know that this URL here is the whole URL for the homepage and um outline light let's go rounded Hill okay and then we'll take I out and hold on there and website works ever feel like when you're coding you just hope it works the way I'm feeling right now I'm feeling Panic that this ain't going to work it work if and we'll do the same thing and I'll be done with this one side here okay co-pilot I'll take it how I knew that okay I'm going do warning here yellow cuz I need to be as yellow this is kind of crazy I don't know if you're watching this jacob that it knew that IMDb is different I muted my mic but I said out loud I said that's crazy that's the right URL that's the right URL that's co-pilot's kind of it's kind of cool that's something all right yeah and it knew that I was trying to make a button and copied the style from up here um it's pretty cool and it knew it want to call it too so it knew it like it was IMDb whatever I'll take it I'll take it sometimes you want to keep it around you know co-pilot's fighting for its life out here yeah all right so let's uh let's run it see what we got and this is the longest page the most complicated page that we're going to build um I would say this is kind of heeters on the sort of the advance side but hopefully it works look at that so we got some buttons we got a pills with July whatever we could probably make these bigger that's really small um but you know I zoom in here you can see kind of it made some um Hills there so but I'm not going to fight with that for now I mean like let's get this thing done so like um that's kind of cool so this is all the information you want here now I need the poster over here and then I just need the overview down here and I'm kind of done kind of cool it's not centered like I want in the page so let's see if I can work on that I must I did something wrong there um so let's see here so I have my title container okay and then this is justify content Center align Center Aline item Center don't know what I do wrong and on line items Center should know we'll work on that later let's get everything else doing and then I'll work on this container and see kind of what it's going on so we can probably collapse this for now and this is our title container and then we have a deflex align items and it should be moving it down but it's not but maybe I just need to adjust this in the title probably we can work on it later okay let's keep going okay so I've got this div here but this is the container over everything and then I've got this div here that just holds my title container and so what I want to do is make another div that I'm flexing across and this is going to hold my poster okay so I'm going to put another div right here so now I have two divs in here and that's going to hold my poster now it knows look at it's like reading my mind it knows I want to put the poster in there but I I'm not going to do that quite yet because there's other stuff I got to do and then I'm going to say div and I'm probably going to have a poster container here because I'm going to move this thing around okay what I'm doing here is I'm flexing these two divs then I'm controlling this div inner div with this this container that just holds the poster okay so we need to check here to see if our poster path is in fact null we'll do it again um kind of what we've been doing here and I'll say if string ring is noar empty and we movie details let's add another one here poster path WR an image statement here null or empty let's go ahead and put in our placeholder because we have seen it sometimes when we' in testing that sometimes movies don't have posters and so we just know doing this over the years got you got to be fault tolerant so that's why we do this stuff to placeholders it looks ugly what you want you're demoing something trust me when I say this if you're just like ah they'll never see that they will that's the one search they'll do the one that's broken on the movie that doesn't have a poster yet did it again so like um it's kind of cool don't think we can have a this is I don't know what I was thinking here I don't think this is valid for an image just alone okay so tp500 movie details all movie poster movie poster path I will take it Go pilot for the win okay so let's look and see what it looks like now and now we should have our poster path and then we can take this and just kind of work with our c SS a little bit to see if we can get it to work and then we're almost done we're almost home here so we got a poster it's ginormous okay and then we've got this thing right here you know um it's also on the wrong side of the page that's a problem so maybe if we can flip it around see if we can do that with our Flex box and then let's see if we can control its size okay now it is going in there so notice too that like sometimes the backdrops aren't the same as the poster and sometimes they are so we just rely on the um see that's got a different backdrop and then there's a different poster here so just depends on what they're doing you know um and if you were really down on this in maybe you could they do have more than one backdrop and so maybe that's something you want to play with but for now this is going to work for us our backdrop and our post are kind of real similar but that's okay all right so let's see if we can move this around let's get rid of it and so we do have a poster container here okay but we have this wrapper div here so the wrapper div is what's being impacted by this Flex column and so we can for this one we can say um order on mobile last this is what's kind of powerful some of these um built-in FX statements here and then we can say on medium break points which is tablet and above make it first and that's going to flop the order of this div and so I don't have to necessarily type it in the order I want because sometimes I want it first Sometimes I want it last and then deflex this whole thing and let's see let's justify let's try to get it in the middle of its div and let's run that let's see what I did there I like our slow jam here ke um Jacob I know I've been I don't know how how much they can hear it on the stream but I've been over here grooving to it it's in my ear the whole time and so now uh you know so this is like a a standard tablet or whatever and so it's like you know it's moving around it's moving around it's going to like and it's going to flip here in a second see it's going to flip and that's kind of what we want you know so uh pretty cool now some of these break points are irrational what I call irrational break points when you squeeze it like this and so really break points are kind of concrete you so like but we can also dial this in with break points if we want and so so that's not totally bad I mean but it's not great but like you know it's not not awful you know we can make it better I think so this is needs to be smaller in there um and then it needs to be pushed down a little bit but you know does work at this point you know and I'm sure if you made it smaller and just stuck it in the middle no one's going to do getting what I'm getting ready to do and you this could be a winner even that and just put your overview on the bottom but that coder Foundry we want to do better and we can do better let's get let's work on it a little bit more um so um I want to work on this poster container and maybe we can work on moving it down um a little bit so poster container now I'm going to pick a size that I think it works and then if it doesn't work we'll adjust it I'm going to set that um it's already asking me to put some stuff in here but I'm going to ignore copot it for that has no idea what I want it's just trying to be helpful um we're going to set the max height 24 rim why do we do that is kind of 200 pixels so but you know whatever we're also going to set the aspect ratio of this and if you didn't know this existed this is something that saw a while back like oh I didn't know you could do that images and so we want to make sure this is in a thin poster format regards to the height okay okay and then we're going to position this one still going to be relative um we played around with some other stuff but um we like it relative seems to work pretty well and then um put a box Shadow on this I'm actually going to copy this in for my favorite box Shadow we should probably put this in the theme Style Just to let note to self out of be like box Shadow is SL box Shadow but um because I like it then I can round this yeah exactly you know uh and then there's like all of these box Shadow sites you know Jacob it's kind of cool I think I have a Styles sheet somewhere with like five different box shadows in it yeah I can copy that over we can give them names cool cooler super cool you know we can name them like ice cream Bobby's favorite Jacob's goto chip box shadow um and so I've got a margin that I want to put around there so um that border radius I we just did I'm rounding the order I'm rounding the full just rounding this square and then I want to put a margin around it um and so margins go from top right bottom left it's like a clock you always think of it in the clockwise um and so it starts out and so the margin on this top we want it to no margin up here we want it to be zero but on the left and right we're going to put two Rim now Rim can be think of it as line break every time so if you thought of like a line coming down and you went two lines over that's kind of what we're doing I'm going to just do two Rim Two Rim bottom and Two Rim left or yeah left no magic to this here's the magic okay let's look at this and I'll come back and do the magic right the too many yeah way too many man I got too happy on that thing man didn't I yeah we were having fun it's probably going to blow up because I don't think it had time to I changed it while I was compiling let me try that again I'm going to attempt to use um all right cool all right so now we have our movie still kind of big I thought it'd be smaller but like you know maybe I spelled this wrong let's make sure that poster can oh all right so a container has a max height and now what I need to do is actually size the image down so so um I'm going to say container then I'm going to set the image height to it and I'm going to say mac x x width is 100% so it can't break the container then um the other thing that I want to be able to do is Max height 100% then I'm going to say object fit cover and what this is going to do is size it to that Max on man oh pilot is CH is now it's messing with me all right now um what this is going to do this is going to set this height to this container the max height it can be and then this is going to be 100% and cover it and because of that I'm hoping that'll make it fit to the size that I want want all right let's see if that worked go save that and hit our chain no code changes are found of course not so R run it if it's not there I need to check to see if my style has if I spell poster container correctly could be a problem there we go go all right still not rounded I'm not sure why it's doing that all right but that's our poster of the size that we want now so now we are sizing this inside its container and it's it's looking kind of cool but now we can move this thing down so check this out I'm going to come in here and I'm going to transform and then I can translate the Y which is the the up and down then I'm going to just say 50% of whatever its container is no matter what break point I'm on or how big that thing is it'll just say oh half of that and move it down and uh I save this and we'll see if it changes sometimes it does sometimes it doesn't it did changed it cool didn't have to hot reload that's kind of what we want so now we've got our poster kind of doing that's kind of cool um and then if we move it around it's going to flip like that got a little problem here we'll we'll address that down here okay in our content area um but that's looking kind of cool kind of nice all right kind of cool kind of looks like the drawing we probably could work on this font size a little bit maybe but um we'll see okay let's get our overview in here we want our overview right here and then we're kind of done with this thing almost all right so let's go back to our [Music] component and um let's look at where this would go so I do collapse things quite a bit so I can figure out where I'm at so I've got this title container and then I've got this poster container here and let's see here and then just actually this is easy I just want the overview just right under this whole thing so we're just going to do it the whole thing here say class we put this in a container here and to make this look good just note that I am um I'm matching the container sizes above here so I'm matching it with this one okay so this container needs to match this one at the same break point and these break points are fluid which they go out to the side and then our titles in the middle and I want this overview to be sized with our poster and our titles in here okay all right so um in here we're going to put another div [Music] um dra this overview I'm sure we're going to need this and um and let's put a be and then at movie else not overview we have an overview here boom [Music] then okay I could stop there put one more div in here may add some more stuff to this if we have time but I I do know that we could put spoken languages I think that's one thing that we can put in here that's coming from here and we can say movie dot details speak language something to cool to add any does it have anything we don't know I just want to show you that we could bring in some stuff that's kind of cool all right um and so these sping languages are coming back as an object there's an array of these guys but check this out this is just show you some Advanced things that you can do with this because we have C on our front end which is like really really powerful all right so I'm going to say languages [Music] languages at string join is kind of similar to what you would see in JavaScript okay so I'm going to join all the the languages comment a limited List come back movie details not going to do this because this is an array it is little this gets complicated Jacob um what I'm gonna do here is like there's some there's some foreign languages in here like Arabic and Chinese and whatever and um we we're going to be biased here and we're just going to get the English name um the cool thing is um all of this object here is built into this object here which is you know so it's totally discoverable what I had to do so I didn't have to go back and look at the object I knew that I wanted the English name but I knew this is an array of values and then this is allow me to filter that array and then whatever filters come back join it into a common eliminer list you know I think that's hot but you know I don't know if anyone else does but see what it does I think it's cool all right so this should be at the bottom and then well I think we're I think we can dial in our UI and then we're kind of done I don't think I think we're pretty much got everything in here um if we have time we may add some genres I don't know yet a lot to do still okay so we got our um our uh languages in here and then we have our overview here but kind of sucks I mean it's behind the poster because we push the poster down and the poster isn't supposed to be there okay it's not so what we need to do is calculate the width of this poster and off set that width and make push this to the right and then we're looking good all right so we can this in our class here in our CSS so let's go back to our CSS here and uh what do we call it movie did we just call it overiew okay overiew and um let's go back to our class here and let's create one called overview here and we'll just show you that you you know you can do math kind of cool right so margin and then so that poster so that poster is 24 rims tall but it also we set this aspect ratio because then we could defer its size um and so what is two divided by three okay know no one can answer but you know if you did that at home we can count that and say 24 rim and know that I know that's the width and I'm going to multiply that by two / by three which you know it's the mark of the beast then um what I can do is add a little padding for support here plus four Rim making up something here but uh that could be four rimmed out then um let's let's give it a [Music] margin top of Two Rim just to make sure that it doesn't um make sure that it doesn't doesn't run into stuff right okay let's see what it looks like I think missing a a closing parentheses right after for I see that thank you yeah just to save you the hot reload grief Jacob Jacob is my co-pilot he's my GitHub co-pilot you just don't know it yet anyone else needs a I give you the monthly rate yeah all right so that didn't work so it's not loading so we'll just run it again and get back in here got a little work to do I can tell you that this is going to work on All Bright points we'll work through that here in a second um but this big bright point that we're working on just to show you kind of how it could work then we'll um work on it and what else we can do okay that didn't do anything okay sometimes okay I've done something wrong here so know what I've done I know one problem I have is that this thing should be underneath this all times I don't know why I did that but just different now fix why it didn't do it but then let's just make sure that these them themselves [Music] put around this just to make sure that it should be blocked man yeah we're good I think I'll check the um Jacob I'll check the uh see if it's getting loaded into the stylesheet should be yeah well you know I guess it's a good sign if the hardest part about Blazer is CSS it always is there it is okay this is a good debug session you always check to see kind of like if you're watching like [Music] um oh uhoh I guess we have a syntax error do I yeah something with the margin left it's crossed out okay there you go thinking all right so I did do something wrong all right fix it for me copilot now I want kopa to do everything margin left c times is it just because of that plus is it just cuz there's no space that's got to be it I will say CSS these Cal things are kind of very super finicky probably what it is CSS for you yay that's it that's it all right so we moved it over it looks good on this but it's going to look bad on this I can tell you it's going to look bad on this and so um over here it it needs to fill the page over here and so enter break points and we need to code some up real quick and then we're done with this thing notice here too what's kind of cool like how this um that little select statement in that array coming back so if you've used map or spread functions or things like that um you can do that inside of an object too right inside a c it's kind of cool um all we got to do now let's fix this and I think we've got this thing cooking what do you think yeah all right let go let's see if we can get it to work here so um what we want to do is break it here small and then we'll look at big and see if we can do that so in our in our stylesheet so let's uh let's work on that all right so up into this point um I don't have any break points so all of these are going to be kind of like um our default Styles and that's how we design um sty sheets which is mobile first which means when I build a media query it's going to be minimum width up okay instead of Max width backwards so this will always work at mobile level unless I override it so that's our kind of our way of thinking um media queries here and so I'm going to write a media query here and I'm going to start at 992 okay and 992 is like a really large it's kind of a desktop all right so we'll start here and um and this is a pretty simple syntax you'll have it memorized after you do a couple million um and if you go to um bootstrap bootstrap has some published media queries and the reason we use boot STP media queries is because if I type MD on something I want these media queries to correspond when that breaks typically and so if you're using bootstrap and you're writing media C you want to use their break points because you're using the break points in their other kind of classes so you kind of want to use the ones that they have okay all right so what I want to do is I want to take this overview and I want to put it right here um in this break point and then then I want to set the default for mobile for this so um probably for mobile I don't want to left it at all and I know that half of that page is going to be over it so that's half of 24 is 12 so if I set this to 12 and I know that margin already has a should have a top on it or something or margin bottom we'll see that should work if not we'll adjust it a little further but boom check it out kind of cool we could probably um put a margin on the bottom of our overview class but that's that's kind of cool so now when it goes out here it works pretty good okay pretty neat right but what we do here um a lot is we spend our time using these um developer tools here and um once this comes out um we use this button here to toggle the devices I'm going to pull this over here and so this is um iPhone so we can look at it on a iPhone Pro and you can look at the width here 390 by 884 down and you can hit the landscape okay that works it could go up here um but it works okay we could adjust that maybe I think it's going to be fine and then we go to our iPad that kind of works and then we flip it over here that does work and um that kind of works that kind of works kind of works I'm gonna call it done at this point Jacob there's a lot more we could do um but you know we could be here all day messing around with it and I might actually work on it some more and if we release I think we're going to release this repo so you may get some more or less Styles in there but in general you know kind of works what do you think yeah I mean you know especially with the the longest movie title known to man you could break this layout one way or the other but yeah it seems to work pretty good and then I'm just looking at this overview is it's okay I mean we could like calculate this one and put it up there for this break point you know or something with like this break point plus landscape or something like that but um I think I think it looks pretty good um Honestly though if any must watching from the school they probably say Bobby you wouldn't accept that you would make me go change these you're probably right you're right but so it's it's okay it's in the ballpark at this point we could add like four or five other um media queries and make it better and maybe I'll go back and do that but I'm going to hand this off to you now I'm going to push this back to you and then can we do one more thing we think we could add genres to it and just have a genre selector or do you want to do paging what do you what do you think yeah I mean we can do genres we can do Pages either one I think paging is probably um between the two more necessary yeah let's do paging because honestly what we only can see this many movies here you know yeah because there may be something after the URI surgical strike that I just have to see so you want to see the 21 most popular movie yeah exactly so let's add a paged component and then we'll call it a day uh form so let me uh push the this to you um and I'll push this to you and we'll may add one more feature to this and be kind of cool sure call it a day session five or six doesn't really matter six maybe yeah guessed at six okay it's pushed all right let's see what I can get sweet all right let me pull it we'll run it and uh we'll do some paging We'll add a new component we'll change how we call our API and we'll be rocking and rolling yeah okay all right so I've pulled the changes I know we've seen Bobby do it a few times I know I agree always run it just to make make sure that everything pulled right and we got to work in code base before I start changing it but let's see we're running got our details nice awesome okay let's do some paging all right um let's see first thing first let's make sure we can call the API correctly um if we can call the API and get the right data then we can code around it and make a UI for it so um I've got here our tmdb API page um for the popular movies endpoint um and it doesn't give me uh well let's see I don't think it works correctly if I page it but let's give it a shot telling me it's a query parameter so let's give it a shot let's see if that works um if not we can go about it a different way but supposedly I can ask for page two that's easy to do a query parameter let's go to our tmdb client we've got already written some code to get me popular movies it's the moviepopular endpoint um but now I need to get a particular particular page back which means I need to take a parameter um and we'll say int page it's an integer can't have half a page um so we'll receive a parameter uh one of the cool tricks you can do for paging at least I like to do it not necessarily right now this will break my code because our homepage is calling this method and um I'm not passing it any parameter so my code won't compile um but what I can do to be kind to others If This Were a larger project More Than Just Me and Bobby were working on it we're using this often I can give this a default parameter of one which means that this is now a optional parameter um and my code won't break it'll happily compile it'll get called and if I don't pass a parameter we get a one back as a page um which is awesome so now I got to do a little bit of work before I I get started um before I plug it in there uh first I want to validate this page number I want to make sure that my page is at least one you know thing things could go wrong in which we might call uh try to ask for page zero or negative one so I'll say if uh page is less than one then instead page equals 1 um I will also check for our Max value um I know because we've used tmdb a few times if you guys have come to our inperson class uh especially recently we've been building a project with tmdb um and I know that they only support paging up to page 500 if you want to see more than the 500th page of popular movies I don't know what to tell you that's unpopular movies but um we're going to make sure that we get uh a maximum of 500 so if my page is over 5 00 it has to equal 500 um just because I know tmdb is going to give me an error if I ask for page 51 um so we'll just double check those coming in make sure we get sane data and then we'll go in here and we'll say Okay I want to get moviepopular and my query parameter it's going to be page equals we use our interpolation here equals page my parameter let me double check that make sure my syntax is right uh yep and Page equals one so that's right sweet if you're not familiar with query parameters calling an API um you can also see them in MVC apps if you are getting a page with parameters uh route parameters it's your url followed by a question mark a name equals a value then if I had more we'd separated it with Ampersand and you can just Trail parameters on there as a query parameter it's part of the URL um and in fact we'll use these here in just a second um but I think that's it I think that works or I hope that works we're going to test that real quick we'll see if we get different pages of results here before we build the UI we'll just make sure our service method works but here in our tmdb client we've done it we've accepted a parameter made sure we have valid inputs added it as a query string and let's go back to our uh homepage uh beautiful beautiful so as we can see um we're calling our service we injected it called it tmdb um we called it with no parameters and it's still perfectly happy to do it because we gave it a default parameter um so just to see what we get with page one I'm going to change it to that we're going to change it to page two in a moment uh and make sure we get different data back as long as we do then uh we're we're in good shape to go ahead and create our UI let's see what we get for page one okay just like we've been seeing Mission Impossible all the way down to Yuri the surgical strike okay let's try it with page two now we'll see if our hot reload is our friend today we'll ask for page two so I'm going to change this parameter to a two we'll attempt to H reload see if these changes go through nice okay all right let me refresh the page sweet all right new movies Elemental etc etc sweet Okay so we've got new movies I can see that my C works correctly now I just have to make it uh a way for our user to be able to change this page easily um and just like we did with the movie details we had a route parameter when I hit uh this details it takes me to slov ID we're going to do the same thing for paging we're going to make it such that when we page we use a uh a query parameter just like we did on our API call um so let's do it first things first we need to make some buttons for for paging and then add those to our page or add that that component to our page and I I do like this component that is actually reusable across projects I've already used this same component in a few projects um so let's go ahead and make one we'll add to our UI folder a new component it's going to be uh I'll call it a paginator razor and um sweet that'll give us a good start I like to put it in a component just cuz there's a little bit of logic involved in when you can press next page when you can't disabling and enabling different buttons and what you can do it at the page level I just think it's easier to kind of break this problem out into its own component um and along the way we'll see a pretty cool technique how we can use uh event callbacks and Blazer which is really cool too uh um but first let's let's write our HTML and this should be pretty easy well let's get our parameters in here um this component is going to need a current page to know what page we're currently on um and I'm going to put in another attribute here called editor required um and what's cool about this it won't stop your code from compiling it'll still run if we don't provide this parameter but it will provide within Visual Studio a warning it'll say hey this component expects a current page and you did not provide one um so it makes it easier for other people to use your components easier for you to use your own components if you're like me it's in a different file I don't remember what parameters are there um so it's a hint to myself too um but to page we need to know what page we're on um we also need to know uh the total pages to go through that's important we can say page one of 500 or however many pages um and that's it for now we're going to add another one here in a minute but that's it for for now um to make this component what I want to do is I want to get uh a div where it's centered and it has two circular buttons in Arrow forward and arrow backwards then in the middle for now we'll just say current you know page one of 50 or two of 50 or whatever the case is um so to make sure it's centered I'm going to give myself a div with a deflex um line item Center that's going to make sure that our text and our buttons are or vertically centered and justify content center it's going to make sure it's in the middle we're going to add a little Gap three to make sure that they're not touching give them a little bit of space between them and now I can have a previous button a span with our current page and a next button that'll be a good start so the span is easy we'll just say page current page of total pages and because these are parameters provided to this component I can just get at them with our at symbol and they're required so they're not going to be null um let's style up our buttons we're going to give them a class of BTN BT BTN BTN primary and this isn't fully going to work we're going to add some CSS but to get it very close to a circular button we're going to use use bootstraps rounded pill class that's going to do is that's going to make the left and right borders um fully rounded a semicircle and then we'll add a little CSS to make it a full circle um and on here what I want to do is I will say let use my bootstrap icons uh bi Arrow left Chevron would work too but I like the arrows uh um we'll do the same thing for our other button but Arrow right yep left and right okay make sure we have the right directions um and then I want these this is kind of the business logic that I wanted to put into a component uh I want my arrow left my previous button to be disabled if I'm on page one and then my right button to be disabled if I'm on the last page whatever that is so I can do that we have our disabled attribute in HTML and um this disabled attribute is going to be either true or false the result of whether or not our current page is less than or equal to one um because if we are on page one we don't want to be able to go back any less than just in case something really goes wrong we don't want to keep going backwards and we'll do the same thing here our disabled button for the next or our button for the next page will be disabled if uh our current page is uh greater than or equal to our total pages so if we got 50 pages and we're on page 50 can't go to the next page we're on page 51 we still can't go to the next page U because sometimes things can go wrong um I think that's it in terms of UI display which is cool um I'm gonna put this on my page just to see if this appears correctly and then we'll type out the logic for what happens when you click the next or previous button so um let's go back to home and let's see what do we got we got our Row for all of our all of our cards okay so below that we'll go ahead and put in a div with a little bit of a margin just to keep it away from the footer and the cards we'll put our page generator um you know we'll put our pageor we'll add the parameters here let's add a condition here we're going to say if movies is not null well actually I can Short Circuit at that if movies is not null and its uh total pages is greater than one I don't need to show a page nator if we only have one page so if we are greater than one we'll put it in here and the only way that would ever be true is if movies is not null so this is our uh null conditional if movies is null it'll stop checking it'll return null instead and null is never greater than one um so I can be confident in here that by the time I do show this page inator my movies is definitely not null which is great uh so I can say uh total Pages well we'll say we'll start with current page current page is my movies response dot I think it's just page yep and we'll say total page ages uhoh it's got a whole extra thing in here um movies. total pages and this would work fine most of the time um but like I saw said before that tmdb only that's say page andate up to page 500 so I also know this response will be greater than 500 uh so I'm going just going to show 500 if it is above that so we'll say movie to movies. Total pages is greater than 500 question mark then it's 500 or it's movies. total Pages uh which is pretty cool this is our Turner statement if our total pages is over 500 we're just going to say it's 500 otherwise if it's less than 500 or equal to um then we'll just pass those total Pages directly in here and I think that's good for our UI let's give that a test see if that shows up for me and then we can work on how to page to the next page in a moment okay we're in we got some movies still looking at page two um okay here we go page two of 500 uh my text is not centered like I thought it would be that's a problem and these buttons are a little bit it may be hard to tell I'm not sure how well you guys can see on stream but a little bit oblong I want to make sure these are circles so we can fix that with a quick line of CSS see if we can get that centered up as well uh so let's look at our paginator oh so yeah they're not vertically aligned because I spelled align item Center wrong we can fix that um and I'm going to add one class here with or not add one class add one style the cool thing here is that um I can do an isolated stylesheet so I'm going to style up rounded pill or I'm going to add a property to it and even though it's being used elsewhere in our application this isolated stylesheet will only affect the class of rounded pill within this component which is pretty cool I think um it makes CSS a lot easier to write so we'll add a page. razor. CSS and we'll Target our rounded pill class and if I know rounded pill already rounds the left side and the right side nicely I just need to make sure that it's uh equal height and width I can just use the same thing we did before for the uh image our aspect ratio is going to be one that'll make sure that our uh buttons have the same height and width at all times which will make them a circle since they're already rounded um so let's see let's see if we can hot reload that nope sometimes it has a hard time with isolated CSS because it does get compiled so it can be hard for it to adjust that on the Fly I guess especially since I added that whole new stylesheet after it was compiled okay and yes our buttons are now nice circles that's beautiful our pages are lined up and now instead of hard coding page two we'll have to uh see if we can modify this um um so let's do it let's go to home. Riser our homepage here um what I'm going to do I'm going to make sure that um we're going to get our pages from a query parameter uh which I think is cool it it allows you to carry state in the URL which means you could potentially anyways um like share URL to a particular page and it'll always go there um I think it's a it's it's a it's a additional form of routing um they can be really handy so I will say Supply parameter from query and we will call this one a there you go co-pilot figured it out we'll call it page so when this when this URL is reached with a query string on there question mark page equals something we'll get that as a parameter and we gave it a default value of one so if you arrive at this homepage without a page parameter we'll just create one for ourselves um which I think will be good for us um so we can do this let's see so on initialized because I'm receiving this parameter here uh the the page number we request from a parameter I'm actually going to change my uh life cycle method here so in addition to oninitialized async there is also a on parameters set a sync which will fire not just when the component first loads it does happen right after on initialized um but anytime the parameter gets changed this method will run again meaning if I'm already on this page and Page goes from one to two it will update this parameter this method will run one more time we'll get the latest pages so uh instead of hardcoding two we will say page our uh property here our parameter from our query string um and let's test if that works let's just make sure that that does what we expect it to do all right so may be small for you at home but I can see I've arrived at my homepage with no query string we're back to page one Mission Impossible uh my pageor tells me yeah page 10500 awesome my back button is disabled I don't see it as clickable my next button is clickable doesn't do anything yet we're going to get to that in a moment um but let's see if I add a parameter here question mark page equals one oh probably should have done two huh page equals 2 do we get a new page of results yes I added that parameter to my URL and I get some new results here that's awesome all right so that works we received from our URL a parameter for our component um which is really powerful we can have buttons that route to that URL we can share that URL to other people if your app is deployed and they'll get the same page you were looking for um so now we can go ahead and um well let's validate our parameters too since anyone could enter anything in the URL we'll do the same thing we did before we'll say if page is less than one page equals 1 if page is greater than 500 page equals 500 nice um let's write a method here we'll write a method in this in this page a private method um it's going to be an async task because it's going to have to take uh do it asynchronously we're going to call this same method we'll call it get page we'll take an integer page um and we'll do the same thing we did here we'll say movies equals get popular movies async um just to make it a little easier to understand I'll say page num page num that's our parameter so this is just a method um that I can call anywhere in my code it can be on button clicks it can be be in responses to different events um I can even call it in my on parameter set a sync so I could just say for example await get page with my page parameter it'll call the same method but now I have a method that'll do this um whenever I want or in fact you know what we'll change that actually I'm sorry we're going to change that we're going to go back to calling it on parameters set and what we're going to do is we're going to trigger a parameter change here um and to do that I need to inject service here inject navigation manager and our navigation manager here is uh built into Blazer it lets us route to different pages it gives us some extra tools let's just change the page programmatically instead of it through an href um but what I'm really going to do is navigate to this same page with a different query parameter um so let's build it let's say our URL is going to be that navigation manager. g URI with query parameter this is a method that will format these query parameters for me correctly which is awesome um and it takes two two uh arguments page the name and the value which is going to be page num and I could do this myself I could use a a template literal like we did before and say slash with a question mark page equals page num I think this is a little bit safer if I decide to change the route of this later on this will uh use whatever current route I'm on which is great um but now that I have my current URL with a new query parameter it updates it if it's present adds it if it's not we can now navigate to it so I'll say nav do navate to that URL and this doesn't need to be asynchronous because I'm not calling that method uh which is great if you're already on this page and you navigate back to it with a new query parameter it will uh not do a full page refresh it will just update the parameters that our component takes so uh because we accept a page parameter we're changing it in this URL navigating to it the whole component doesn't need to reload but the parameter does change and then this method fires again which gets the movies one more time for us um and now for the cool part because the button for changing Pages lives in this pator component I have to tell this pator component hey I have a method that I'd like you to run when one of those buttons is clicked so what I can do is I can add a parameter to my paginator one that we're going to uh guess it doesn't need to be required it is an event call back that's the type of parameter and um copilot's pretty smart we can give it what we call a type argument in those angle brackets to say hey I need a method which takes this type as a parameter in this case an integer and we'll say page or on page change that's what we'll call it and this is pretty cool this is truly just a parameter that takes in a a method um but it's almost are very similar to adding your own custom events in in JavaScript for example um so it's some code that this component doesn't really care about or know about just knows it needs to run when something happens um and then our homepage will decide what to do when when that is that event is fired so um we'll write a couple methods we'll say we'll make a next page method um and this page is going to say pretty much exactly that if my current page is less than my total Pages if it's equal to we don't want to go to the next page my current page is less than total Pages increment by one and then this is how we call our event callbacks we will say on page change invoke a sync that's the call back parameter on page change we want to invoke whatever parameter we were given and pass in current page as a parameter and we'll do the same thing for previous page private async task previous page we say if my current page is greater than one same thing we will decrement our current page and then call that parameter we were given whatever method we were asked so just like that this pator component can take in an on page change method and increment or decrement the page we're on call that method so that whatever is using this component can update this state accordingly um which is great so now I can go back to my home and I can say in this page I will say on page change what I want you to call is my get page method and you can see I've passed in this method as a parameter here this method accepts an integer parameter just like um the pageor component asked for and when we get that new page number we want to go to we'll go to our current URL but with that page as a query parameter which I think is pretty [Music] cool I think that'll do it I hope let's see if H reload works and then we'll see if our code works okay how reload says it works let's see um okay so I'm on page two since I was still running the app no I got to start it again oh no I didn't need to start it again the reason it didn't work is because I didn't tell my component when to call those methods whoops I wrote the code next page and previous page I was so excited about that code I said wow that's going to work co-pilot you're my best friend thank you so much I never call these methods though so that's kind of a problem um and I think this is the first time we're doing it on this stream uh I can tell these buttons what to do when you click on them I can say at on click when this button is clicked um this one is going to be previous page the on click in C for this method is the previous page method same thing for this button on click when I click this button run the next page method beautiful beautiful now let's give it a shot now now that we've made these buttons actually do some let's see if it works fingers crossed okay we're in we're on page one see can I go to page two nice scrolled to the top my query parameter has been added new movies we can keep that was blazingly fast Jacob I you know I I had to wonder did it load the new movies yeah by the time time you scrolled to the top it had loaded them which is awesome um all right got page three of 500 we'll go back yep loaded before we get to the top yeah and there's no page refresh so it's like almost like magic yep um that's a cool thing it it's almost deceptive that we um we navigated to a new URL but Blazer was smart enough to say wait that that's the same page you were on this just has a new parameter so it UI with that yeah it's awesome so one thing I wanted to bring up if you get back to the code is the um I think it's the current page um public variable there and how we're not passing that into the method at all it just um because um it's being changed on when it's coming in it's also being updated inside those next and previous as well so like um the updates we don't have to like like a lot of times you'd have to pass a value into this method and try to figure out which one it is and do any of that kind of cool yeah you yeah because that value yeah that is cool that value comes from our parameter our query parameter and it just naturally gets updated bler says oh this is where it comes from sweet I can fix that yeah so it's being passed into the component and then turn around adding to it and being passed back out and then get page if we go look at the get page on this component here this page here um it's getting its page numb from somewhere yeah it's getting its page numb from uh our our call back here so okay next page says hey go ahead and call that method and provide this parameter after I've incremented it right okay and it it could be shorter I could just say current Page Plus One or minus one that is another option as well and it would work just the same yeah it's okay that's cool cool I mean like it's really slick yeah so it's cool P I think putting on two lines makes you understand kind of what's going on you could put it all in one line but um it gets kind of cryptic after that yeah I mean and and the JavaScript uh developers out there would love to hear it you can use Lambda expressions or Lambda methods in these on clicks so I didn't even need to make a previous page I could Arrow method but I would have I wouldn't do that but I I I do feel like it reads better this way than the other way um I do the other thing I wanted to know is like the disabled thing I think that's kindli too where we're looking at current page and we're running some logic to set a value of an attribute of an HTML liit which I thought was pretty slick I think it's awesome but it it it takes a minute to wrap your head around which is why the biggest reason why I said actually this should be its own component yeah it talks to the home page but like I don't want to have to worry about all of this logic within the homeage I just want to put it in the component and say whatever take care of it not my the other reason you don't put it in the homepage is now we can lift this component anytime we want to page anything we just use it and that's other reason you can put it into the component CU now the component can just literally be copied and put on some other page and long as you pass it a number it doesn't really care it brings back a number calls the function and that function does whatever it needs to do kind of cool I'll give you guys a spoiler alert I uh if you guys watched the stream earlier in the day um before our live coding session they showed the galactic relics API uh and the challenge involved and when I built the client app for that challenge because we we can't issue a challenge if I can't finish it of course to paginate on that I literally copied this component exactly I I grabbed exactly what I just CED up here pasted it in that project worked just fine just worked was awesome okay well I think our work is done what do you think yeah I feel pretty good about it could do another feature but like it's 7:30ish so our time so we've been here all day so like I feel like that's a pretty good um starter app um we'll try to package this code up and push it on GitHub for you make it a public URL yeah and um I think we can do that but other than that still got people watching which is kind of crazy so like you know like late in the night um appreciate you guys watching us uh code I do think that you should watch some of the stuff tomorrow from Microsoft um this is a very detailed project that we we put out probably the most detailed project that samples will be shown all week on Blazer so if you want to come back and you know give us props like subscribe smash the like button you know by Jacob coffee right I'd be willing to say if you watch those those um those sessions in NETCOM tomorrow or the rest of the week you might even come across some examples and and say oh you know I saw Bobby and Jacob do that that makes sense yeah a lot covered here yeah so like what I want to do one of the early comments we got in this live session the guy says hey you're not showing render modes and um what I want you to understand is that this will work in server or web assembly the reason we're doing this is because it's easy to post on a website using netfi and that's why we use the client side project um the renders to me are the sizzle on this Stak man like compon components um how you build it those callbacks we just showed that is really where the True Value the true um expertise that Microsoft brought to this framework is really really powerful so um this is why people are going to adopt it they see these components and building Pages like wow that's it's kind of cool you know so like you know like conditional parameters on attributes and H2 elements all that stuff it just works and it's really slick yeah all right I think we can call it a day let's go eat dinner and uh we'll see you guys on the next show next time good luck guys and keep [Music] good
Info
Channel: Coder Foundry
Views: 29,332
Rating: undefined out of 5
Keywords: coding bootcamp, learn to code, dotnet, .net, c#, programming, software developer, coder foundry, portfolio, web dev portfolio, web developer, web dev, get a job, javascript, html, css, get hired, web developer portfolio
Id: 5NDIqqw7HrE
Channel Id: undefined
Length: 331min 15sec (19875 seconds)
Published: Tue Nov 14 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.