Building an Online Ticket Store with Blazor WebAssembly

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everybody uh welcome uh we have another webinar for you i feel like i've been doing these a lot lately so uh thank you thank you for joining uh and i'm definitely excited about today's guest just was just talking to him uh before we started and uh i'm really excited to see what he has to talk about today so um before we kind of invite him on obviously you can tell from the slide that's visible right now our guest is steve and he'll be talking about building an online ticket store with blazer web assembly but before we invite him on let's do some housekeeping first of all if you have any questions and you're watching us on youtube right now feel free to drop those questions directly into live chat uh we have some folks backstage who will try to answer those questions and we'll take some of the best questions and ask them to our guest today so feel free to ask them a common question that gets asked by a lot of people is is this session recorded yes it is uh you're watching it on youtube right now and it will be available on our youtube channel at jetbrainstv if you're watching this in the future well yes obviously it's recorded you're watching it so uh feel free to like and subscribe uh and if you like this content uh it really helps it out uh you know to get us more webinars and stuff so uh short of that um let's invite uh our guest on right now uh steve hey steve how's it going hello hi good thank you how are you pretty good i know we were talking you're in that co-working spot and that background is uh wild yeah thank you um yeah so apologies if there's any uh weirdness because yeah i've just moved house and i'm in a weird place so we'll see how we get on okay yeah uh so yeah i'm um i'm excited to talk to you today and see your presentation about blazer and blazer web assembly i'm also excited to maybe pick your brain a little bit about net six uh it's wild to think that dot net six is like right around the corner and uh just reading the latest there's a lot of enhancements to blazers so uh maybe at the end when there's questions we can talk about that but as of right now uh i'll give you the stage and you can kind of give your presentation brilliant cool all right um hello everyone thank you for having me um as mentioned i'm steve pierce i've got um i've worked a bunch of places in my career but for the last couple of years a co-founder and working on powered for tv that's a wrestling streaming video service um built entirely in blazer and so you're welcome to check that out and there's a code rider if you want to have a free month trial and have a look so my idea for this webinar was a hypothetical scenario that we uh powered for tv started selling tickets to our wrestling shows so we thought let's see how far we can get with building a ticket store um and then we'll cover a fair amount of things so i think the difference for this that i was going to go for is maybe we'll talk about quite a few different subjects but maybe not in as much detail as lots of videos that talk about one or two of these at a time uh so yeah there's there's a lot to go so you probably just get started cool um right let me just open this um so you should be able to see ryder uh we'll go from the start so i'm running dot net six preview one and i've got a solution already created but we're going to create a blazer webassembly application so if you do a new project and choose sp net core web application can zoom in a bit and then a time for blazer web assembly and then give your project a name uh and then it will create it for you i've actually just pre created pre-created one just to save a little bit of time but this is uh just as you'd get if you're new except i've done one minor modification in my launch settings.json i've added in this uh this command and that's going to give us a net watch so in uh net 6 they've introduced something called hot reload that's pretty awesome so for blazer that we're gonna see in a moment uh when it runs uh we should be able to make edits and see them pop up in more or less real time so we won't have to keep starting and stopping the application um so here is the default oh everything runs a little bit slower i think when you're sharing your screen but here is the default laser um web app that comes and so we've got a page here which i just uh we won't dive into how everything works but let's just have a look at the code so in blazer we have a pages directory by default and inside that we've got a few different pages so a calendar a fetch data and an index which relates least three links here if we look at this index page we'll see that this is a page because we've got this page attribute and then this hello world is this so i can say hello ryder and hit save in theory if it's behaving it's a little bit slow the first time there's a few exclamations yeah so you'll see that it's updating instantly over here um and we have this page title here so that is a new component in net six which will update the title of our page so if we call this um p4 for powered for tickets um and save that we should see let's zoom in the this title up here updates so that's pretty cool laser is a component uh app so we've got the survey prompt so that is a shared component uh so in here we've got some shared and it's components of this survey prompt and it's just some html razer syntax which most people be familiar with um and we also take some parameters uh which we can then use and you see in here that we're passing in this title parameter um so if we just change that to how is ryder working for you uh it's updated there um cool and so then we'll just go into some detail about where all this other stuff comes from so if i just minimize these i hope you can see it all right um oh under the shed as well actually we've got this main layout uh so here we've got this at body and that's what the pages are replacing so i could just put an h1 star [Music] around that and we'll see the start of our page and i'll just say start again the end of our page cool so very cool very cool stuff yeah thank you and say let us uh start to actually make this look a little bit better so i'm just going to remove all of this noise around here we'll save that and we'll see it's that's the page because this if we're using uh bootstrap five by default i'm just gonna uh surround uh all of my pages in a fluid container so that's just a bit of formatting that'll come in handy later i think we want to have a nice heading so i'm just gonna go to get bootstrap.com oh not get boots get boobs strap.com and i'm going to just pop to examples and headers and i'm gonna pick this header and i'm just gonna steal the html for it and i'm just gonna edit as html i'm gonna borrow that i'm not going to put it directly in here i'm going to create a new component called main header uh just just to keep the naming so this is main layout so i'll call it main header and i'm going to show you how to add a new component in blazer so if we right click add blazer component new component i'm going to call it main header as well this should in a moment [Music] this should find this new header and it sorts itself out uh and we can now see this main header so [Music] by default uh this is what you get for component just a header and an empty code section i'm going to delete all of that and drop our header in and with a bit of luck it'll look vaguely nice and we're not going to have an image so i'm going to delete that and this simple header here is that title so i'm just going to call that p4 tickets save that and we're only going to have two nav links so i'm going to remove all of those i'm going to have this home link and i'm going to call the second link basket because we're going to have a basket page in a little bit and i'm going to update these hrefs [Music] and now we shh i might as well just rename this counter page i'm going to rename this page basket and we're just going to still this page and let's um this page has the uri uh of the url that we're gonna match so i'm gonna update that from counter to basket and i'm just gonna write the word basket a few times [Music] oops uh with the hot reload sometimes you'll get a prompt here uh which says you want to restart your app so i think where i renamed the page i update i upset it and so i'll just tell it to restart and then hopefully our basket page should appear and this is just the account page here uh one thing you notice here i can jump between this home page and the basket page and we want this basket to highlight blue like this when we're here and for this home not to so that's pretty standard navigation stuff so if i come back to my main header we'll see on this home page that we've got this active class which is giving it this blue tint if i just remove that and hit save we should see it looks normal so i want this active to be quite dynamic as we swap between the pages fortunately there is a blazer component built in called navlink that will do that for us so we can just replace the anchor tag with a nav link and it should update the end for us and then give it a second to restart we should see okay on the home page it's working on the basket page that's showing that home isn't part of the reason is because this href is just gonna match forward slash to start with so we can say um match equals [Music] and so that is going to look for the whole [Music] url um cool so we've got our basic navigation for the demo in place and you know the sense that i'm getting like as you're going through this is like the workflow and the feedback loop is kind of awesome like you can just kind of do what you need to do and it just kind of is handled by it so uh it's it's really cool so yeah absolutely and if you think before you'd have to keep stopping and starting to run and get this like it it really speeds you off and makes you productive um having the having that.net watch um okay so we now are gonna go and try and get some shows so we'll try and get some of the latest shows to show to show you um and that the customers see what tickets are available to buy so i have in the background over here an api which i've already created um which we will run we'll just give that a second to load up yeah it's it's the curse of screen sharing your machine just loses like 20 power so that's okay um yeah so i've got this shows api so if i just hit try out execute we'll see that we get back a bunch of shows uh some basic details such as the name the name of the promotion which is the company that runs the shows price and a few alphabets so we want to make this api call from blazer and then show something nice in our application so how are we going to do that if i just close all the that we have here there is an example um already in this fetch data page where we inject an http client and make an api call so i'm just gonna um still what we're doing here but let's do it from scratch for ourselves back to our index page uh i'm going to do at inject http client http client so this is going to use our dependency injection to register an http client um to inject the http client that's registered and we'll see where that's done in just the moment let's just have a quick look at that now so i'm going to come to the program.c just like any app we can register uh services in here as so at the moment we're doing add scoped a new http client with a base address you you looking at this and see that's red and angry this is because in dot net six they've introduced uh global using statements so you can create your usings once and you don't need to have it in each file if you don't want to uh this current version of rider that i'm using doesn't or isn't aware of that so it was a bit red and angry although it actually compiles and works fine but i'll just bring that using statement in here to make it happy [Music] um so i'm going to change we've got the base address that we're setting up in here which is currently using uh the host environment i'm going to change that and we're going to choose this swagger i might include the v1 information so we've decided to version our api in the url so let's do that and then if i come back to my index we're going to add a code section in here and now there's various life cycle methods inside laser but a very handy one is this uninitialized async so this um is called once in the lifetime of the component after all of the dependency injection has happened and after any if you have them parameters are set if you have any one-off code uh for a component this is a good place i'm just gonna paste uh this code that we had earlier i just need to make this an async method and update the name of this http client i'm going to we're going to call this get from json async method which will make it get your request and then deserialize it into the generic type that we pass here and so i've got this api that i mentioned before because it's all.net front-end and back-end can actually share the api contract so there's this show summary model which is here so i'm going to de-serialize to that so if we say show summary model and with a bit of luck ryder will realize and let me confront the project and add the using statement and then our request uri is now this shows so if i just borrow that because i've been chose um oh and then we'll also want a variable or a property which i'll make private to store those in and i'll just default that to an empty array [Music] awesome and then it shows equal http client get from jason so if i just go over here and save that but when it actually loads nothing much will happen here because we're not actually using it this yellow squiggle is pointing out the fact that this could be serialized to null i'm not going to worry about that for the point of this demo um that's just a null warning what i will do um i'm going to delete this survey prompt and the delete this and it's not this header actually because that's not good coming shows save that and then because this is raising syntax it could be the at sign we can do four each and i'm going to say vast show in shows and let's just do a paragraph and see [Music] put out the name and see if we've got the shows back which we do so we can now see we've got uh the api call was successful and we're bringing back some data i would like to uh put the show that we're going to format here into its own component it feels like a an isolated thing which will be uh keep the code and the page clean so i'm going to come into my shared here um actually the the um it doesn't have to be shared this is just a convention that you could have components in any directory it really doesn't matter but i'll carry on i'm going to add the directory and i'm going to call it shows and i'm going to keep everything related to shows so and it's good i'm going to add another laser component summary so this will be just that high level summary of the show that a customer won't want to click in uh i'm not sure why it's angry but we'll we'll find out in a second i'm sure oh no it's fine um let's get rid of that in here in this show summary we're going to take a parameter so we're going to pass where we're looping through these shows here and we've got this show summary i'm going to pass that show summary to do this component show summary model i'm going to i'm just going to call that show i'm gonna save that and might do let's just see if it works we're gonna do an h3 and do the show.name hit save and come back to our index and i'm gonna delete that we're going to show summary and we're going to pass the show equals at show and close that off and hit save and it hasn't worked so the problem here is a problem that you'll run into a lot perhaps that this page doesn't know what this component is um so actually we're missing a using statement so i can fix this problem to people tickets web client shared shows and hit save and it's back although i i think i've got an error in the component but we'll fix that in a moment uh but yeah you'll see this has now turns this kind of greeny blue color i'm a little bit colorblind so forgive me if i'm not 100 sure what color that is um but if i remove this using statement again you'll see it goes to this purple color so that's usually an indicator that you're missing and i think you might get a build warning as well does does blazer have this concept of um you know an asp.net core mvc there's this concept of view imports it's kind of like a global file you can put into a directory that has like shared namespaces and yeah there's something like that in blazer yeah excellent question and so there is and so i if i borrow these usings i'm going to cut them and remove them so that will upset the page and this is actually a useful when you make make an error in blazer when you're in hot reload uh it will show some meaningful errors like this so this is i can't compile my uh razer pages but inside this imports.razer um we have lots of those uh almost like global usings but for all of your razor pages so i can drop those in here and hit save and it will recover and fix itself and that just means that we don't have to add these usings to each page or component and pages are just components anyway so yeah that's a good good question um okay so let me just see what we've done wrong here and so we're passing in a show summary model um is that unhappy oh i'm not quite sure what's going on there i think maybe hot reload went funny but yeah so we're now pulling those shows in so let's just take a moment and maybe we'll try and style this to be something vaguely sensible so i will probably cheat a little bit as well and use the bootstrap site and i'm going to go to documents i'll go and search for cards and find something that yeah maybe this which looks half decent for the sake of the demo i'm going to copy that here i'm going to paste that html straight in and hit save and we've got some cards for these shows and so let's just format this quickly i'm going to remove this style that was in this html and we've got an image source and so we do on our show have an image and an image url so if i save that you should hopefully see some images which is giant so i might just in this index i might um use a little bit of boot strap oh that's the wrong thing uh put these in a div and i'm going to give that a class of row so this is just some bootstrap formatting of the page and i'm going to say click div class equal a col um six [Music] maybe we might do four that kind of looks okay for for the sake of this demo and then if we go back to our show summary i'm just gonna pop put in a few more properties from from here so this card title i'm going to give that the show got name and this card's text we've got a show got uh script i'll put the location in there and we'll add some buy tickets as the button that we've got here cool it's looking looking okay um and just actually because i quite like it i might add this for the uh name of the primary oops scroll scroll down to the bottom of the page which doesn't help that let me scroll back up and i wanted to borrow this bit of markup here [Music] and let's say show got from promotion main and yeah let's not do so just a fun thing you can do in blazer so if we wanted to add some styling specific to this component we can so this is the show summary.razer i'm going to right click and add a new new file we'll collect show summary.razer.css and give it a second it'll sit under the show summary.razer and any css that we type in here will only affect uh this component so let's give it a second if i do this at star i think that's a selector that will choose everything let's just say background color black just prove that it's only affecting this component or let me rerun this watch and see if it works i think uh there's a few bugs with the dotnet watch which will hopefully be resolved for net six release um i think some of the release candidates um oh i just started the wrong thing which i just restarted the wrong thing which doesn't help let's try restarting this one yeah i think it's important to tell people that uh dot dix uh is still a preview uh also writer support for.net sex is still kind of ongoing so uh steve you pointed out the uh global usings i've actually seen a dev build where that works so yes awesome it's good okay let's see if this is gonna give us a black background it should yep there we go i think i upset the hot reload when i added the css in um i don't actually want a black background boom sorry um [Music] i might do um i might just add a bit of a margin at the bottom of these cards there is a bootstrap style called mb so if you did like mb-3 that gives you a margin bottom of three which is kinda nice yeah yeah yeah no that that's that's true um i was just looking for an excuse to do a bit of css isolation but yeah it's a very good point oh this this is perfect whatever you're doing it it's perfect so don't mind me awesome no no it's fine um i might just add a box shadow when we hover over [Music] over the uh the card as well just for another example of of some css isolation so if i've done this right we get a nice little preferable preference but a nice little hover but yeah you see that that just affects whatever i need that card anyway but yeah it's a nice uh little demo css isolation um okay let's let's carry on so one thing here because this is all running very locally it's all very fast so i wanted to just pretend that this api call isn't as good so for example if i go to basket and then back to home you'll see it loads almost instantly if we await a task door delay and add in 500 milliseconds which is half a second delay we should see if i go too fast get them back home [Music] oh that that seemed let me have a longer delay or my hot reload or me has made a mistake so if i go home just refresh this i might just restart this hot relay one second um what i'm hoping to see is there'll be a gap the is noticeable between loading the page and then making the api call and displaying the content so what we'd like to do is here we go so i think it's working now what we'd like to do in that moment i'll just show a little loading uh something so uh what i will do is add in a private ball is loading here we'll say that's false well by default it'll be false so let's get rid of that and at the start here i'm going to say is loading equals true and is loading equals false at the end and we'll hit save um [Music] actually i probably didn't need to save that then because i haven't used it i'm just going to add in our you know markup up here this app if is loading let's span and just say loading dot [Music] else we'll show this component that we were showing before [Music] save that and if hot reload is keeping up when i come to home we'll see this loading now so in case you missed it i'll zoom in on the spot and go here see the little loading there [Music] what this this loading i think will be useful so i like to pull this into its own component but rather than just doing that i thought it might be nice just to show a little bit of how you test components starting with probably the most basic component that you can have so in this handy time saving directory i've created a test project using b unit which is a library that sits on top of your favorite test runner such as x unit n unit or ms test um and it helps us test our blazer components um so if i just come into an example test um this is using b unit but it's also using b unit fluent assertions which is a library that i've written but it gives us this nice uh fluent syntax that you can test the an interesting thing here is that our tests are actually an eraser file rather than a cs file or a c-sharp file and that means that we can do at and write markup so this is a test which we're saying please render an h1 of test and that should have the markup of h1 test and have tag h1 and child markup of test um so let's just run this example test and it should pass and then we'll we'll write our own test for our new component from scratch cool so i'm uh we're going to put a new component in this shared directory so i'm going to create a new directory in here to match and grab shared and then add a new blazer component i'm going to call that loading and the naming convention i'm going to choose is should so all of our tests will read loading should and then our first test will call loading should show loading when is loading um one final thing for our test setup we can inherit from test contacts so this is a b unit thing which gives us access to some methods to make things easier and i'm going to say render component loading which i haven't yet created and we'll say that that should have markup and we're going to say that we should have a span of loading. that we did before [Music] and that should be our first test [Music] i'm going to run this test and because this component doesn't exist it will hopefully fail um and on the assertion that it does fail as it's taking a moment to run i'm going to go ahead and start creating yep there we go it's failed i'm going to create the component so we'll do a new place component we call it loading um and we'll just leave it as that default for a moment we'll have to as we have before uh import the using so i'm going to uh add a reference from my test project to my project and so we can get that and then we'll just quickly say uh p4. whoops people.web shared [Music] and then we'll see again that this has turned to that uh greeny blue color and then if we run our tests this should fail because uh it'll say that the markup does not match and it's just a little bit slow because of the screen share that's really cool i i guess while that's loading uh i have i have a general inquiry uh in regards to um do you find yourself when you're writing tests for blazer components do you test the markup or are you really testing that general data is in that component um i'd say a bit of both for some very simple components like this i think testing the markup makes sense for more complex components personally i would check that it's got the um like the core information so i would probably check that it's got the for this component over here on the right i'd probably check that it's got the name and the promotion and the address but in a way the um i can then use hot reload and style it and maybe change the order but without breaking the test so i'm looking to make meaningful tests that aren't super brittle um if that makes any sense oh yeah that i mean it's funny you use the word brittle because that's kind of the thought that was going through my head like how do you make these tests so they're not brittle especially when you're on a team with designers uh that could maybe be evolving the look and feel of your site you know if you were testing the exact markup every little additional class could break all your tests right that's probably not what you want yeah so i i might do something and let's just make this see if this test is passing first and then i'm i'll show you oh i've upset it now um [Music] oops let me just stop this running just uh run unit tests uh i like how you keep mentioning you've upset it like it's some kind of a dragon it's a it's a it's a beast to be tamed oh there we go say one thing that like sometimes i might do is in a more complex component i might use something like a data test uh class equals loading and then from my test uh wherever that's gone uh rather than saying should have markup i might um try and get um i think there's a few extension methods that i might be missing but get by data test class it's not gonna help me um yeah i can't remember which usings i need so i won't waste too much time but we've got some extension methods in the um uh the fluent assertions laser so i can get my data test class and then i might get check that that has the content um oh yeah because i haven't got that it's uh i'm breaking into that distance but it should have like child content of loading and something like that and then i might pick the bits i'm interested in with some tests and check that they have the content and they aren't removed and then if you're worried the the html might start looking really um like weird you haven't got control you can use as some libraries uh for snapshot testing uh my my brain has gotten blank as to what the one that you can use with blaze it's called i think you've had the person on as a guest before i think it's simon crops verify yeah yeah so you could use something like verify in conjunction with pulling out these interesting bits to test um and then that that's quite a nice way so you you're testing the core bits but you can also have a quick cursory look at the output html and but it depends on your test strategy well that's just it's it's neat that it's all kind of up to you to figure out the best testing strategy but you still have the full strength of like the blazer component model and you know you're you're used to the test runner that you're used to inside of rider or uh resharper and stuff like that so very yeah yeah absolutely cool um right that's a better move on a little bit from testing um what i'm gonna do is create a new page so that when we go to buy tickets we um uh or actually um i might just show a quick state thing so there's a bit of an annoyance when you go between the basket and home that it reloads everything so one basic ish way we can do some state management or the reason that is because when we swap pages this index page is just destroyed and then recreated so we're not keeping that state so what i'm going to do is create a new class to hold the state which i'll just put in here and i'm going to call that shows uh it's it's lucy view model pattern from mvpm although i'm not sure if any uh die hard nvpn people will tell me off doing it wrong but i'm going to just copy the these properties from our index page into this view model i'm going to make them public and i'll add in a getting set let's just get a bit more space huh i think um we might struggle to get to the end and finish all the cart and everything um so we'll see how far we get oops especially when i struggle to add a property let's just choose summary model chose what's why is this weird there i think let's remove that one um a little bit more screen of state for a moment once we do this i'm just gonna do the same for this ball is loading and um i'm gonna inject that model which we'll register in a moment in our dependency injection uh so i'm gonna choose view model i'm gonna call that shows you model here and then we'll update this shows viewmodel. is loading so you we're gonna use that and show you what a little shows and rather than this code here which we're gonna initialize i'm gonna create a new method on my shows view model um which i'm gonna go to public pacing task and i'm gonna call that load shows and i'm gonna drop that code in here and i'm going to inject the http client into the [Music] [Music] so that's now all inside we've just extracted what was in this index into a into a class and i'm going to do the shows view model dot load shows and we'll and in our program cs i will just quickly register that um out as scoped the same as we've got for this http client [Music] that one hit save and uh i think when i was doing the tests i might have stopped this from hot reloading so i'm just going to start that running again and we'll take some screen real estate back so this should load in a moment sounds like there's a wrestling match going outside yeah so sorry for the background noise oh it's not your fault is it distracting oh no i was just making a joke um uh here we go so we're still showing this is loading but um actually inside my shows view model if i just come over to this one um in here i'm gonna actually add a all of as loaded and then we'll say after here has loaded equals true and i'm just going to wrap this all in and if statement has loaded if has loaded or we'll just return early and not make the api call again oops oh my gosh typing is hard okay soon again i've upset the beast but we'll reload that [Music] that would make a great sticker or t-shirt the blazing beast um yeah we'll see that we're not losing that state so we're not reloading this each time so it in blazer when something's scoped like what is its scope to because in asp.net core it's per request right so you're making those initial requests what's the scoped inside of blazer yeah it's it's a good question so inside blazer web assembly so this is running in our browser it's the same as a singleton because it's considering your browser session a scope so whilst we're inside here it's it's the same as a singleton if it's on the server um i'm not i'm not 100 sure for um uh server side but yeah for the scoped okay yeah that makes a lot of sense because uh like i'm thinking about it in respect to asp.net core i'm thinking well isn't that just gonna reload the data every time but being a singleton yeah you're right so yeah so yeah it's a nice way there are a few different ways you can share state um including you can use like cascading properties which i was going to show but i'm not sure we'll have time um but you can also there are libraries for redux uh or that sort of thing so if you're coming from a javascript background and your um you like those libraries there's some open source equivalents um i'm aware that we're coming up to time i'm not sure uh how much further we can get i mean it's okay if we go over by 10 minutes you're at 57 minutes now uh so it's okay um there are a few questions but uh you're welcome to continue um so maybe let's just quickly add a page so when we click this buy tickets we'll go to page four show so um we're just going to go into the show summary component and we will uh that make that link to shows and then the show show id we'll hit save on that and then we're going to come in here and create a new page so in writer it's on the blazer component but we can choose page and we're going to say we're going to call this page show details and our url will be shows and then a different way of getting parameters rather than we've seen this wave passing a parameter where we add it to the actual html but for pages uh we can pass parameters in the string up here so i'm going to say show id and create parameter here show id and then we should be able to show show you the show id and check that these links are working yeah we're we're coming to that um okay and what i will do uh to say to save a bit of time um i won't make an api call to get detailed show but what we'll do is add in a form to um to be able to add tickets to our basket and so for that form i'm going to capture a few components so i might just add a new class in here and i'm going to call that um a basket item did i spell that right basket item [Music] did i choose a random thing um [Music] public class basket item and i'm gonna add in a property of a uh string show id and then property of a small for a price um because i'm not actually going to get the real price by making an api called save time i'm going to hard code it at 12 and then we're going to have an integer of number of tickets and then in my show details we're going to create a form an edit form and the model is going to be a basket item so i might actually create a public uh sort of private basket item in here basket item [Music] you basket item we'll just new that up inside here and i'm going to bind to this form to well say the model is this basket item and yeah i might just full screen this just for a moment and then on submit i'm going to create a new method that it's going to be called when uh when we click the submit button in a moment so uh let's do that why have i made there's a strange parenthesis there i don't know in the arts i think it's because i put the class name in rather than my instance of the model i think yeah i think that's happy now oh sorry my uh my setup in this office is starting to uh fall apart a little bit you've you've upset the beast i've upset many beasts it seems just going to pop a button in here and just use strap in here and say submit so in theory we should have a submit button in there um [Music] i might just have some html to borrow rather than typing it out [Music] i think if you look at the uh oh yeah i just pasted very strangely um i seem to paste with some formatting issues one second [Music] let's just fix this real quick [Music] yeah back up the pre-typed code um failure that and see if it's happy at all um let's just quickly full screen this um so that is complaining because so on your on submit attribute on line four you have an extra parentheses at the end of the uh oh yeah oh that's what you oh sorry yeah yeah no worries okay let's see if that's happier it's the the fun of pair programming um okay so we've now got this drop down um i might just default as basket items to the number of tickets of one then we'll just have a quick look at what we just did [Music] okay so i've created a an edit form here with the model basket item which is uh just giving some context to the form and you can use it for validating multiple properties at once i've then added a label for this input select where i've just made a drop down using a for loop for the number of tickets that we're going to use with a small calculation of the number of tickets times the price and then a submit button [Music] let's just actually do something [Music] when we have submitted i'm going to say if that's submitted yay submitted [Music] yay submitted um and then what we can do is uh we can set like it's disabled uh uh the drop down we can disable if if uh sorry has submitted and then perhaps will be the same on on the submit button [Music] so if i've done that correctly [Music] oops i'm still hot reloading i'll just pick something hit submit and now i can't resubmit so that that's a very quick look at some forms um just going to look next at some of the state of actually keeping the basket and adding and removing some items but i think we're going to go over um yeah i mean um yeah we're we're at one hour and seven minutes so um maybe we maybe we have time for one more i don't mind going a little bit over uh if you want to show something specific um yeah if if that's okay um sorry for anyone at home who's on the schedule um one thing uh a different way of managing state um is using cascading parameters so i'm just going to add a new blazer component and i'm going to call this cascading basket state and this uh this uh code is gonna have some methods on it or this is gonna have the state for what's added to the basket so i'm to create a property and use a list for speed basket item state items and i'll just initialize that as a new list then i'm actually going to add in some methods here or public forehead add to basket and we're going to take basket item item and we'll do a basket item store add the item and hit save and then uh we do an equivalent for the removed but i won't do that at the moment but we'll uh this is where we'll do some fun stuff and we're gonna create a cascading value and the value will be ourself um and then this this um we'll also take a parameter of um property over render con render fragment and i'll call that child content don't worry if this is a bit confusing but we'll see it in a second and i'm going to call child content so we've created this cascading value passing itself as an argument and child content and then if i go to this app.razor which we haven't actually looked at yet this is where we set up the routing and how a lot of the routing happens and where we choose the template i'm going to wrap this whole thing in my cascading basket state body and then what that will do is make available the state that i put up and for itself to all components underneath it so if i come into my um uh where are we the show details i can choose of a very special parameter of cascade interactor and choose public cascading basket state and i'm gonna i'll just call that basket state say yeah sans and on this callback i can i now have access to the component here that we just created so i should be able to do let's come on to one of these pages so we can see at this point i should be able to do basket state and because we created this ad basket method i'm going to pass in this basket item that we had before and that should add to the list and here let's just um outside of this yay submitted i'm just going to drop in a [Music] h1 i would say this is my basket [Music] and we'll loop through each of our basket items so i can say bar items item in [Music] state and paragraph let's say it's in dot oh hang on sorry basket state basket items and then item dot show id item dot uh fry of number of tickets and then dot number of tickets a little bit ugly but if i've done it right we should see [Music] this reloads see our baskets i'm going to just add in and oh i must not be selling the show id somewhere um um where did sorry i'm just gonna full screen this for one minute um oh okay i'm um we're missing when i initialize this i might just add a quick protected uninitialized and we'll say basket item dot show id equals show id here and if this refreshes oh sorry i think i broke it yeah i think there's an error on the line with red um oh yeah there you go okay so i've done override task and there is a non async version which because i'm not doing anything here i should use [Music] so that's happy thank you now this should be happier [Music] and then if i add something to our basket we can see it there um if i go we'll just pick another random show i'll add some of those to the basket and we'll see that the state is shared um and then we could add like a remove button we could in our main header up here we could inject that component as well um speeding parameter prop of the basket cascading basket state and then in our uh it is basket we could do a fast hit state or basket items for counts [Music] and if i hit save there oh i think over [Music] throughout i've randomly added the word key there and let's just remove that so if i add something now uh oh actually we'll see this hasn't updated if i go to home uh it's updated when i've changed the page so there's another common problem that you have in blazer if you programmatically do things sometimes it doesn't know that it needs to re-render the page so if i come to our cascading basket state where we've got this basket items.add we can actually say um what's the my brain has gone blank one second we can [Music] i'm going to google or bing force there's a component to re re-render i think it might be chain update sorry change let me just quickly check sorry it's uh my brain has it's okay it happens mel melted after an hour um is there some kind of context maybe yes so there's um there's a method it might come up from oh state has changed i could have just used intellisense and yeah so there's a method you can call so if you programmatically do something um and the ui doesn't update you can say state has changed and that will tell blazer to update the state so now where before this wasn't updating here when we did it it now updates instantly so we can just do the same with a random other one we'll add something to the basket hit submit and see it's gone from one to two yeah that was that was totally worth it by the way so i'm glad uh i'm glad you wrote that i personally didn't know you could cascade values like that uh in blazers so that's kind of a cool feature to create some kind of global state uh especially in like shopping cart scenarios it makes a lot of sense to like have a global shopping cart that everything has access to so it's very cool stuff yeah absolutely so um yeah i mean we've got a little over but it's okay we still have about a hundred people watching so that's pretty good um i'm looking through the questions i'm trying to figure out if there's any good ones um well one person asks well do you have a sample project where you kind of show some of this stuff uh or will you make one available for folks to to access um yeah i can make this isn't available at the moment but i'll put it on github and i'll finish off a couple of the loose ends and i'll put that out for an example that we can then link to and i'll add a few notes as well okay uh great i i guess uh this is maybe a personal question asked by someone who's new to wasm and the concept of wasm um but like in your opinion uh why is wasm in your again in your opinion is why is it better than say javascript or writing javascript yeah and i wouldn't say it's better i'd say it's different i think uh for me it's i don't write javascript every day but i'm i've done i do a lot of back end in c sharp and dot net so for me this is a lot more approachable and i'm very productive in it whereas if i was going to write the equivalent in react or view it's completely different ecosystem so i think if you're currently writing apps in in a javascript language or something else and you're happy go with it if you if you're like me and you aren't working in that day day-to-day then maybe this would be useful based on your experience and your team's experience as well yeah i think the thing that kind of sticks out to me like doing a lot of view and react versus blazer is you literally didn't have to set up your build pipeline or assets or figure out those kind of things so getting started with blazer especially if you're coming from.net can be a lot simpler uh for a team that's maybe focused a lot on c-sharp f-sharp and the dot-net tooling uh right so um so somebody asked a question and maybe this is a good question to talk about powered for tv um but are you finding any users coming to your site using uh internet explorer six um no we haven't but we um we did add a bit of javascript the um it detects if you're using internet explorer and we'll pop off an alert and be like please use a modern browser so um yeah like fortunately um because of the nature of our website we don't have to support that if you did want to support old browsers you could possibly look at blazer server side and which will open a signalr connection and it will do all of the state logic on the server and and then that prob made i'm not sure about ie6 but it would work with older internet explorers for sure okay i i guess i have one other personal question for you as you write an app like powered for tv do you find yourself leaning a lot on community-built uh components or do you find yourself rolling your own custom components or is it a mix of both um it it's a mix of of both really um i think where we were quite new we built some of our own components and then found there's community versions so um when blazer web assembly first came out it didn't support updating the title so we rolled our own version uh and then found the community version which was much more elegant so we switched to that and now in dot net six they're supporting it out of the box and but there are things like state um local storage management which uh i think uh is it blazerize oh i think chrysante is the author of that yeah yeah exactly so and there's a lot of good stuff from them and there's lots of good things in the community and so yeah it's a mix um and there's there's lots of component libraries as well so if you're building something which which is useful maybe more business than consumer focused um well both really but um yeah there's plenty of options out and because of the component model it's quite nice so you can bring in nice components and as as you wish yeah i guess the last question i have is as you've kind of started your blazer journey and you've rolled out a blazer application have you found yourself in a situation where you wanted to implement something and maybe just couldn't or has it been mostly smooth sailing um so dot net six gives answers a few of the frustrations so this is currently running in dot net six um and this is pre rendering on the server so if i load here you don't see any loading switches whereas this site ow well that looks with when you full screen um let's go half screen um this site you'll notice when i refresh here we get this loading just for a second so you can pre-render your site on the server uh what used to happen before dotnet 6 was that it wouldn't you didn't have a way of keeping the state so you would load the app load the page and then you'd have a flicker of refresh whilst it made the api calls again so that's resolved um because that was quite frustrating so that was a big thing for net six for us um everything else you can do and you can interoperate with javascript so if if there's something you feel you can't do but javascript can you can you can still do it okay excellent um yeah i think that's really it for uh questions um there was a lot of people on this webinar so thank you to everybody who watched um thank you steve for uh doing this uh so uh let's uh let's wrap this up uh let's bring on the um end credits here i'll add it to the stream oh there it is uh so uh folks thank you for watching again thanks for steve uh for demoing uh blazer and how to build uh an online ticket store this is a really fun presentation so i hope hopefully everybody enjoyed it if you want more information be sure to check out uh jetbrains.com forward slash rider for any new writer information uh be sure to follow us on twitter for the latest news uh steve kind of demoed some dot net six features uh so i would i would suggest you follow us on twitter to see what the latest uh work we're doing with dot net six if you want some articles please go to blog jetbrains.com.net that's where uh the advocacy team writes a lot of content and puts out a lot of news also be sure to follow and subscribe to this channel jetbrainstv on youtube if you want to find out more about what steve's been doing with blazer and his wrestling video site be sure to go to powerd4.tv he did give out a uh coupon code at the beginning i believe it was ryder is that correct yeah so if you're a big wrestling fan be sure to check that out uh it it was really fun i was watching it this morning so definitely go check it out uh for folks uh be sure again uh you know to like and subscribe this channel if you like this content uh we'll add more uh based on our subscriber count again thanks steve for giving this presentation and thank everyone for joining uh we'll catch you next time yeah well thank you for watching you
Info
Channel: JetBrainsTV
Views: 5,464
Rating: 4.9629631 out of 5
Keywords: Rider, Blazor, WebAssembly, webinar, resharper, .net tools
Id: L2w5A4bMDKk
Channel Id: undefined
Length: 88min 3sec (5283 seconds)
Published: Tue Sep 28 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.