Ionic + React - Tutorial for Beginners 2020

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi and welcome to this course my name is Max and this course is about ionic and react to Awesome technologies which we're going to combine in this course to build cross-platform applications that means web apps and native mobile apps for Android and iOS now this course is packed with content and we'll dive into the different concepts step by step no prior ionic knowledge is required you will learn it all in this course you just a basic react knowledge you should know what react is and you should have heard about react hooks if you don't know that my react the complete guide course might be a great resource to take before this course so let's have a look at what will be in the course in this first module we're getting started I will introduce you to ionic why we use it give you a brief refresher on react and let you know how ionic and react work together so this is a super important module to make sure that we all have the right foundation right thereafter we'll dive into some ionic basics and with that I really mean just ionic because it turns out that ionic also works standalone and that something we'll have a closer look at in this second module but right after that we'll of course also combine ionic with react you will learn how these two amazing libraries work together and how you can use these two technologies to build amazing applications thus far will only have built web apps though as you will see by this point we only have a web app but we're all here because we also want to build mobile apps well no worries I got a whole module dedicated to that I will show you how you can turn your ionic and react web app into a real native mobile app for both iOS and Android so an app which really can be installed on real mobile devices now when you're writing code sometimes things go wrong so therefore we'll also have a module on debugging where you can learn how to find and fix errors and even if your app is error free you of course want to make sure it looks good and it incorporates your corporate identity or a common theme ionic gives you rich tools for debt and we have a whole module in this course where we will dive in detail into the different styling and theming options ionic you now since our main goal is to build mobile apps with web technologies we of course also have to find out how we can get native mobile navigation patterns into our app I'm talking about things like tabs a side drawer or a push and pop navigation there is a whole module on that of course where you will learn how you can add those navigation patterns easily into your ionic react app and you will also see that they look good out of the box now up to this point we'll have learned a lot about ionic and react therefore dad will be when we dive way deeper into ionic into its component library and explore the many components it offers you will see how you can use those components where you can learn more about them and how you can configure them of course most apps don't just have nice components and a nice look and feel but you also want to interact with your users now there will be a module where you learn how to handle user input how to validate it and how to manage your application State this is also where you will really see which parts are controlled by react and which parts are controlled by ionic now as I mentioned before we want to build real mobile apps right so of course you will all learn in this course how you can use native device features like the device camera or the file system to store data and best of all you will not just learn how to do that on Android or iOS devices but you will learn how you can easily set this up so that it works across all platforms including the web yes we will be able to use the device camera in a web browser now of course by that point you will have learned a lot about ionic and react and it's super important that you don't just know which features exist but that you also build apps that follow common patterns and practices and that are optimized which is why I added a whole module where we dive deeply into a app optimizations and explore how we can optimize our code to make sure we're shipping the best possible application to our users and speaking of shipping apps of course this course comes with a publishing module where you will learn how you can publish your app as a webapp onto a server or as an android app to the Google Play Store or as an iOS app to the Apple App Store so loads of content included and with that let's start and let's dive into the most important question first what exactly is ionic and why do we use it so what is ionic ionic is two things actually it's a web component library and it's also the name of a company the company behind that library now to make sure we're all on the same page I should probably clarify what web components are again web components are a custom HTML elements in the end so you can build your own HTML elements and you can do that on your own with JavaScript if you're interested I got a course on that too totally independent from this course totally independent from ionic but you can use vanilla JavaScript to build these custom HTML elements which you can then use in your page or on your page and ionic is just a collection of pre-built web components now these web components ionic offers you look gorgeous they are absolutely stunning they also look very professional and their exact look changes depending on which platform your web application is being served for so if you're visiting a web page let's say on your Android phone it would look very Android following the typical Android style and if you would visit it on an iOS device you would have a more I Wes ish look off that web app so the look and feel automatically adjusts and that's important the look and feel because we're not just talking about a different look but also the animations behave differently and look differently now with ionic with these ionic web components you can therefore build beautiful native device like web apps so we're still talking about web applications here normal web sites or the front end of normal web sites but with very little effort with very little custom styling rules and HTML structure you will get a great looking web application you would still write all the logic you want to add with regular JavaScript with or without any framework now the cool thing is ionic as a company has not just worked on that web component library but all the released another technology another tool which is called capacitor now capacitor works really really well together with the die on ik web component library capacitor is a tool which allows you to turn any web app into a mobile or actually into a cross-platform app which you can serve as a native app on iOS and Android as a native desktop app or also still as a weapon and I'm really talking about native apps here iOS or Android apps created with help of that capacitor tool would really be distributed in the respective app stores so I'm not talking about apps that look like native apps I'm talking about real native apps you can think of capacitor as a wrapper around your HTML CSS JavaScript web application the front-end web application which normally would run in a browser and with that capacitor tool with that wrapper you actually produce real native apps which you can upload 2d respective app stores so that users can get them from there and therefore these two tools developed by the same company ionic work together really well because with both combined you can build beautiful native device like web apps which you then convert into real cross-platform apps with capacitor and that's ionic now a brief word about the history of ionic in previous versions version 1 and 2 of ionic it was basically one tool that had these custom components these custom elements back then only for the angular fronted framework and it had the portability to build cross-platform apps also kind of built in since ionic 4 we have a split and since then we really have that web component library and that capacitor tool where both work independently but where we get the most out of them by letting them work together so we know what ionic is and we heard about capacitor why would we use that well if we only think about ionic the great benefit is that we get great looking apps with very little effort we don't have to do much because we get all the Styles all the HTML structure out of the box and we just have to compose a user interface with these web components we get by ionic so we can focus on our core business logic which means the logic that really makes up our application which we typically write in JavaScript and we don't have to focus as much on the styling and the HTML structure now you can use ionic stand alone without capacitor if all you want is a web app that looks good you can use ionic to achieve that you can also use capacitor stand alone without a onic and then you can wrap it around any JavaScript HTML CSS web app and turn that into a cross-platform app which makes it easy to distribute that app to all major platforms without having to know anything about mobile development and that's the big plus of capacitor you don't have to learn Java and the android framework you don't have to learn Objective C and Swift to build iOS apps you don't have to learn C++ to build desktop apps instead you take what you already know you leverage your web development knowledge and you build a web app which you then with the help of capacitor ship to the iOS App Store to the Android Play Store with the Apple fan installer as a desktop app and of course if you want still as a web app hosted on some server so whilst you can use each tool standalone combined you really have the best of both worlds and you can build native mobile apps with your existing web development knowledge and you can do that really really quickly as you will also see in this course now therefore in this course I focus on this combination I will also dive into ionic standalone and capacitors standalone will be self-explanatory by the time we in this course but you really are able to build the most amazing applications if you combine these technologies and then using ionic with capacitor is a great alternative to learning Java for Android and Swift and objective-c for iOS development or anything like that because you don't have to do that you take what you know and you build for all platforms so we know that ionic is great and capacitor is great and the combination is really amazing now what about react because that's an ionic react course why do we need react and all of that well we don't need it you don't need a front-end framework or library like react to build apps with ionic and capacitor they work totally independent of any framework you don't need react you don't need angular or view or anything like that you could build such a cross-platform app with just ionic and capacitor and vanilla JavaScript your own HTML structure and your own CSS Styles but using one of these major frameworks makes riding real apps much easier and with real apps I mean realistic apps bigger apps and if you think about it you don't need angular or react or you to build normal web apps either you could do that with just HTML CSS and JavaScript we do use these major frameworks and libraries to make that easier for us as developers so that we can focus on on the core logic that makes up our application and we don't have to manage all the nitty-gritty details about showing or hiding elements adding elements dynamically on the page showing modal's manually we don't want to write all that code on our own as a developer we want to focus on the real things that make up our application on the complex things on creating rich user interfaces and user experiences and that's why we use libraries or frameworks like react or angular or view in non ionic and non capacitor apps as well and for the same reasons we use these libraries there we can add them cue an ionic capacitor app to build even more amazing applications with ionic and capacitor and react or angular or view in no time and ionic does really work with any fronted library or no library at all as I mentioned you don't need one but you can therefore use it with react angular view whatever you want and I do have an ionic angular course as well in case you want to learn that combination besides the combination we have in this course which of course is ionic with react so long story short we don't need react but using it makes our life as a developer much easier for the same reasons why we use it in non ionic apps and as you will see the combination of ionic capacitor and react is really really amazing and makes it so fun to build awesome cross-platform apps so now that we know all these building blocks how do they work together how does a typical ionic project look like so we're building an app and when I say app I really mean a cross-platform app we're building a web app and an iOS app and an Android app and we want to do that all with one code base and only with web development technologies we don't want to do that with Java or Objective C we just want to use HTML Javascript and CSS so of course we can write that code on our own we can write our own HTML CSS and JavaScript code and we would have a fully functional web app we could serve that on a web server and we would be good to go now when it comes to JavaScript as I mentioned before we want to make our life a little bit easier we want to focus on the difficult parts and that's why we would probably add a framework like react or a library like react in this case or a framework like angular or view now it's totally optional you don't need Ted to build a web app but often you will add it so that you can build more amazing web apps now with that we have a regular web app with HTML CSS JavaScript and react now of course this is an ionic course and for all the reasons I mentioned we want to add this ionic component framework and here I'm really just talking about the web components not about capacitor we add that so that we have to write less HTML and CSS because we get more pre-styled widgets you could say more pre-styled HTML elements we can use to compose our user interface now with this box we would have everything we need to build an eye on a gap and we could surf this app as a web app or as a progressive web app this is what PWA stands for in case you don't know progressive web app is a web app which leverages certain native device features in the browser if possible and if not possible it will have fall backs which may be all the works offline in general you could say PWA is an enhanced web app and if you want to learn more about that good news I got a course about this as well where we dive deeply into progressive web apps now I want to point out though that with this tech stack here so with this box at the top of the slide here we really build a normal web app we could just turn it into a progressive web app it would be very easy but the key takeaway is we have a web app here now of course that's not enough we want to build for ios and android as well maybe also for the desktop well that's where capacitor comes into play we add capacitor into your project this extra tool which acts as a wrapper around our app and with that we can build for iOS for Android and we will get these app bundles which we then upload to the respective app stores and together with an average rule called electron which is not the focus of this course we can even build a desktop app if we want to and this is the attack stack we would use in a typical ionic react project where we then use capacitor to serve our app to all these platforms now as an extra tool which I haven't mentioned before we'll also use the ionic CLI the ionic command-line interface which is a tool we use in the well command line of our operating system to create ionic projects to manage them to run a development server so basically to interact with our project during development it is basically a replacement for a create react app you could say or to be very precise it's a wrapper around create react app so this is how an ionic project looks like and this is what we will build in this course ultimately so we know why we need react and we know why we might be interested in ionic and this capacitor tool I mentioned how does ionic and capacitor and I'll kind of use these words or terms interchangeably because they're from the same company so how do these tools work behind the scenes ionic and capacitor well when we create an ionic project an ionic app we write some code in react for example but as I mentioned you don't need a JavaScript framework technically so we write our JavaScript code with whichever framework we want and we probably since this is an ionic course throw in some ionic web components to have these beautiful components which automatically adapt to the underlying platform to have the Android or iOS look and all these beautiful animations so we have this app now you learned that you can use capacitor then to turn this into a native mobile app because the blocks on the top that's basically a web app right it's a regular web front-end with react and ionic so only web technologies there and then it's capacitor which turns it into a native mobile app but the question is how does capacitor turn it into a native mobile app does it take our web app code so HTML Javascript and CSS and compile this to a native code so does it translate our existing code to the Java and objective-c equivalents for Android and the iOS platform or does it compile it to machine code which runs on mobile devices or does it use another approach you could think of where it takes your web app and wraps this into a mobile app what does it do well it does the second thing it takes this web app and wraps it into a native mobile app into a real native mobile app now what's that what's this wrapped web app thing how does this work well in the end once we're done with everything once we are done working on our project with ionic and capacitor we want to have a mobile app which we can distribute through the App Store's so which ultimately can be installed on different devices right so we want a real mobile app which you can download and install from app stores that's our goal and that's what we can get with capacitor now capacitor works such that it essentially gives you automatically behind the scenes a very simple mobile app which acts as a wrapper for your web app and it does so by the end hosting your web app ends at a so called web view now a web view is just a technology which is supported by both iOS and Android which is basically a screen in a mobile app which takes the full screen which hides all other displays you might have in there and which hosts your web app which you build with react and HTML and CSS and JavaScript and ionic so which takes this web app and hosts it on a local mini server that runs ins of the web app you could say so that to the end-user it is like a totally normal native mobile app you won't be able to tell a difference you as a developer therefore are able to distribute it through the app stores and it can be installed as a native mobile app this mobile app also thanks to capacitor which acts as a bridge between your hosted web app and the underlying operating system has full access to native device features like the device camera so capacitor does all the wire up work to make sure that your ionic reactive has unlimited access to everything a normal mobile app would have and you really should put that into quotes because you have a regular mobile app in the end here and of course you have one thing though you have a slightly worse performance than in real native apps which you create by writing native app code so which you create by writing Java Android code for Android and objective-c or Swift code for iOS but I know that this sounds very intimidating let me tell you from experience that you won't feel that performance anywhere in 99% of all apps there might be niche cases very performance intensive apps where you might feel a difference but chances are that those apps actually are not really programmed in the best possible way and could also have better performance if they were done right and of course you learn the right way to do it right in this course there are many apps out there in the app stores maybe already running on your device which use ionic and capacitor and where you won't be able to tell a difference so don't get intimidated by this this really is an amazing approach of letting you leverage your existing wept of knowledge and get a real mobile app in the end and this is how it works behind the scenes it's not really so important for you as a developer it won't influence how you write your code I just find it interesting to understand how that works behind the scenes but with that let's move on so we know how ionic works behind the scenes and of course step might bring up one valid question which alternatives do we have two ionic and again I'm using the term ionic here kind of as a summary term that also includes capacitor now with ionic and capacitor we can build those wrapped web apps as I mentioned so as I mentioned multiple times now you utilize your existing knowledge and you get a real web out of that now of course one alternative which I won't even show here because it's so obvious is that you build a real native app by learning Java and the android framework for android and objective-c or Swift as programming languages for iOS the obvious disadvantage of doing that is that you have to learn two brand-new programming languages and respective frameworks and you won't really be able to use this knowledge anywhere else then for mobile app development so you have a lot of work to do to build apps there as another disadvantage even if you learn all those languages you have to build two apps from scratch you won't be able to reuse any Android code in your iOS app or the other way around on the other end with ionic you use your existing knowledge you only need to learn one programming language JavaScript and do you react framework of course and you then write the app once and you automatically get an Android and iOS app which even looks good on the respective platform thanks to ionic without any extra work so that's the huge advantage there but which alternatives do we have maybe we have other tools which also allow us to reuse our existing knowledge and write code only once and we do there also is react native which also allows you to write native apps with react unlike ionic it does not use this wrapped web app approach instead it in the end compiles your views so the markup language for what's visible on the screen and your JavaScript code is hosted in a mini server you could say that's also running side by side to those compiled views so it's not entirely wrapped that has this compilation step which might sound more attractive because of performance reasons but as I mentioned you won't really feel that performance disadvantage and I'm serious about that and in addition you also have to learn and use styling syntax for using react native it does not use native CSS you don't use HTML there you use an HTML ish language or you could say and in general it's a little bit more work nonetheless it is a decent alternative and if your interest I do have a full course on that as well which you can of course take and then we have another great alternative and that would be flutter flutter is not following an approach where you use web development knowledge it actually uses a brand new language dart which is developed by Google flutter is a framework for dart which is also developed by Google and it also however then uses the starred language and a lot of features which are built into flutter a lot of components which look gorgeous and then you also only write code once and you get an iOS and an Android app out of that this also is then compiled dart the entire app is compiled to machine code and therefore you can get that extra performance if you really need it somewhere you have a lot of built-in components which look beautiful and it really is a decent alternative but of course you have to learn that brand new language and framework so it is more work then again using what you already know I also do have a flutter course however if that sounds interesting to you and you also want to learn that that being said all three alternatives here are great they each have their advantages and disadvantages this of course is an ionic react course it is an amazing choice because you will see throughout the course how fun and easy it is to build mobile apps with it and therefore let's continue with this now I know I know I have been talking a lot we should get started now and we will soon no worries but I briefly want to walk you through the ionic history because it is important to understand it to understand which version this course covers and which version you should learn ionic is a company as I mentioned and they released this ionic framework and this entire toolset that allows you to create mobile apps and the dead so in 2013 with ionic 1 now back then this was a framework which only supported angular 1 also known as angularjs so one JavaScript framework and it also didn't bring its own convert touch to mobile solution so it didn't include capacitor instead it was based on another open source alternative named Cordova and it could be a bit clunky but generally it worked fine in 2016 we got ionic 2 which was based on the brand new framework angular 2 which was totally different than angular 1 and in 2017 we saw ionic free which was basically an enhancement of ionic 2 which also included better support for not just mobile apps but all the four progressive web apps so for the first time we had a real cross-platform solution where we could build more than just mobile apps you could say now that's the past then we had a huge very important new version in 2019 and that was ionic for ionic and for changed everything the ionic team moved away from angular they now supported every framework or no framework at all if you wanted that with vanilla JavaScript because now ionic was really just a web component framework prior to ionic 4 it was an angular component framework all those components were built with angular now they were built with native web standards so with the web component specification with vanilla JavaScript and therefore this was the first time I onic components worked with every framework this was also when they released capacitor their own alternative to Cordova which because the now had full control over it really fitted into this whole equity in a nicer way and which in my personal experience is much nicer to use than Cordova that being said capacitor is and was fully backward-compatible to all the support existing chordoma plugins but in this course will focus entirely on capacitor because it really is the future of this cross-platform mobile app development with ionic now since then they release new versions and we got new versions coming out all the time but unlike in the past every new version does not mean that everything changes instead we now have gradual enhancements smaller improvements and of course I will keep the scores updated to include these smaller changes because now not everything changes but only as I said small things that's the history you are learning latest version of ionic with this course and it is the latest version which you should of course use to build cross-platform apps with ionic capacitor and in this case react so now finally let's get started and for that let me show you how you can get the most out of this course now of course it's a video-on-demand course so watch those videos at your pace you can slow me down or speed me up in this video player if I go too fast for you now of course this course has some prerequisites you should know basic reacts if you don't know that definitely learn it first otherwise fooling along will be very hard but then to really fine-tune everything to your requirements follow along at your pace I always recommend that you code along we will write a lot of code in this course there will be chances for you to practice what you learn and you really do learn the most if you just will go it along and build your own app along with me you find code snapshots attached to the last lecture of every module so that if you get some error or you can't reproduce what I had in the video so that you can use those snapshots and compare your code to mine or temporarily replace your code with mine to find out what went wrong so take advantage of that now of course also if you're facing any errors or you're having any problems you should debug your code on your own use the normal web development debugging tools like the chrome developer tools and also if you're getting errors read those error messages use Google and try to fix them on your own now of course I will also provide some support I'll come back to that in a second but this really is how you learn the most so I would encourage you that you really do that if something goes wrong now if you absolutely can't find a reason for a different behavior or for an error you can of course ask in the community that discord community which was linked and also in a Q&A section of this course where I will do my best to provide fast and friendly support for course related questions I can't help on personal project though but also don't just post there and read there but also try to help others because ultimately this is how you learn the most if you help others you can learn way more because you're challenged to think about a problem and find a solution and this is how you ultimately get the most out of this course so finally let's get started with ionic and let's actually really get started with ionic so I mean with just ionic because it's important that you understand what I wanna guess and how this ionic thing really works what web components are and how you use them so that you then in the next step can combine that knowledge with react I find that important because you probably already know react you will learn how to combine it with ionic but we have to cover ionic first so in this module we'll have a look at how we can work with ionic without react so how we can really just use that because I mentioned it react is not mandatory no JavaScript framework is mandatory you could use ionic with just vanilla JavaScript and we will then also see why we still might want to add react though even though we technically don't need it and when I talk about ionic for one I of course also always meant ionic and capacitor so these two important technologies you could say that are managed by the ionic company but I also of course mean all the different things that make up a Yannick and ionic apps and ionic projects you'll be working on and the most important thing there of course will be the user interface components you'll be working with these are two examples which actually exist and you will see them all throughout this course and I will show you where you can find them all but these are essentially HTML elements but of course not HTML elements which are built into the browser like this which browser understands like this but instead added and unlocked by ionic by adding an ionic script import into your page and then by some JavaScript code which gets executed there to basically define these elements to the browser so that the browser knows what to render when it sees these tags that's the idea behind web components and that's what ionic utilizes it's a web component framework however ionic projects typically consist of more than just HTML pages with these special elements for example ionic project as we will work on them throughout the course will all make theming and styling easy they embrace vanilla CSS day heavily utilize a built in CSS feature which is called CSS variables and also many other things and you will see all of that throughout the course as well one thing you can already memorize is that you will typically use vanilla CSS you could also use sass and so on if you preferred that but you can write beautiful apps with built-in theming so where you for example set a color only once and then use it everywhere with just CSS and as a side note if you want to learn more about CSS and CSS variables you can also have a look at the CSS course I created together with manual now when our important concept which is incorporated into ionic and which will also be supported out of the box in ionic react app Slater is navigation in mobile apps you will see that we have some typical navigation patterns like using tabs or a side drawer and ionic will make it very easy to use such navigation patterns and to for example add tabs to your application when our important concept which we need for building modern user interfaces is state management we need to be able to pass data around and to ensure that when we do something in one place of the app let's say when a button is clicked something happens somewhere else and this is also something which is kind of built into you ionic it gives us some tools to help us there but I can already spoiler this a bit this is all the one thing where react will help us and one of the reasons why we might want react now when we also expand the term ionic a bit and we include capacitor in the equation then we can also tap into native device features and that is something which is of course super important with the help of this capacitor technology which is developed by the ionic team and which they offer integrates perfectly into ionic apps we can use the device camera get the user location write something to the device storage and much much more and these are all things we'll also do in this course you will learn how to use the device camera take photos and store them that's all included and last but not least when we talk about ionic they're always whenever crucial tool that has to be included and that is the ionic CLI but also all the different features Ayana gives us to manage our projects the ionic CLI CLI stands for command-line interface will make it easy for us to create projects to test them and also then to pack everything up to optimize everything Publishing so that you really can easily take your eye on a gap and put it onto relapsed or in the most optimized version possible these are all the things as I mentioned state management that's where react will be important native device features that's where a capacitor will be important and for now in this module will actually focus on the UI components so that you get a feeling for that and see how that works and then throughout the course once we also combine ionic with react and we create a project with the ionic CLI we will step-by-step introduce all these different features so that by the end of the course you're able to build real native mobile apps or actually cross-platform apps with ionic and react so we get those ionic components as I mentioned these HTML elements which are unlocked by ionic and we will start using them in just a second they will look like this this for example is a component that we can use once we included the ionic script into our web app into our website into our HTML page it's named ion button and that's of course an HTML tag which is not supported by default if you would put this into a HTML document like this it would not do anything it also wouldn't throw an error because HTML is actually a language which is quite forgiving or to be precise browsers are quite forgiving you can use unknown HTML elements and the rest of your page will still render fine but for this element to bring something onto the screen which we can see it with which we can interact and which really has everything this button should have here for dad we will need ionic in this case so we will have these HTML elements which we use like normal HTML elements they also as you will see throughout this course can have attributes and properties which we can target either by a JavaScript or when we add it in markup like this we can just add attributes like we always do on HTML elements and they will always be able to emit events so for example on this button we'll be able to listen to a click well enough of the talking why don't we just get started and do this then to get started let's visit ionic framework com and there you can learn more about ionic always a place worth visiting I can also recommend their blog to learn about the latest developments of ionic but for now let's just click on platform here and then ionic framework I basically want to get to those docs here now these Doc's here are pretty good you can learn a lot about ionic here I absolutely can recommend checking them out but of course I will kind of replace these Doc's with this course for you I will show you all the things that matter but these stocks are always great to also have a written guide or maybe dive deeper into some components some concepts which we only use a bit maybe so in here we can get started by going to installation and then here packages and CDN now we will soon use the CLI no worries which is this tool that allows us to create local projects but for a very simple project we can just use a CDN so basically we can import anionic JavaScript package which lies on some server which we can just include so if we click here we see these free HTML elements copy them and now create a new HTML file anywhere on your system in any folder of your choice here I created a file named index.html in a folder named ionic react and you can store this anywhere you want and I opened this in Visual Studio code Visual Studio code is a free coding IDE which is great for web development you can get it for free from code Visual Studio com it is available for all operating systems and you can simply download it from there and install it and then open your code with it and I just like it I use the dark plus theme here in case you're wondering why it looks the way it looks for me your dark plus and I also installed two extensions which I would recommend that you also install the first one is the material icon extension it's optional but it changes the file icons to look the way they look in my course here so if you like that look you can go for that extension here and I also got another extension installed and that is prettier and that will help us with automatic code formatting so that if I press a specific shortcut which you can find under preferences keyboard shortcuts and then if you search for format document this shortcut if I press this the code will automatically be formatted to be prettier and easier to read these are two extensions I would recommend that you use of course you can install more I do expect that you already have a development setup since react knowledge is recommended and expected for this course so I will not dive too deeply into that but that's the setup I am using now with that I got this HTML file it's an empty file right now an individual pseudocode I can just type HTML and then choose that second option and hit enter we get a basic HTML skeleton now here under title we can insert these free HTML tags we draft from the ioniq website and you can also change document title here of course a bit if you want I'll name it ionic basics now with this we have a very simple HTML document which has no body which is empty right now and we can just open that for that I'll open it in finder and then double click on it to open it up in the browser here it is so this is this page running in the browser I can open up the developer tools to see if we got any errors right now we don't because although there isn't much on the page of course but we will soon change this now we got that on the page and now let's add a new HTML element but one which is not built into HTML which is not regular HTML the iron button just add this like this an opening and closing tag and in between I'll add click me now of course normally this wouldn't work if you temporarily cut those three imports we add it and save this file and reload you see just click me here but yea nothing happens it doesn't look special if we inspect it we can see that the browser detected this element but it didn't know what to do with it well that changes if we bring back those free imports and we saved us again now if we go back and reload this page oh look this looks more like a button we can tap it and of course nothing happens right now if we tap it but you can already see that without us writing any JavaScript or HTML this seems to be more than an undetected HTML element and indeed here in the dev tools you can also see there is this strange shadow root thing and yeah in there we got stuff so something happened here and if we open a console we of course also get no error so this is now a button and now we can interact with this button here we can add our own script let's say here at the bottom little inline script here in HTML and we can select this button and store it in a constant width document query selector and selected by its tag this is possible iron button like this and of course this is not react code this is vanilla JavaScript we will switch to react soon no worries and we can now add an event listener here to the button if you want you click listener for example and register a function here I'm writing an arrow function which will fire whenever this is clicked hopefully so we can console.log clicked here to see whether it works now if we save this and we go back and I reload and I click this we see clicked here on the right in the console window of my dev tools so this is working and why is this interesting because it normally would not work it isn't a normal HTML element that look we have here and all the features which are built-in of which we're currently only scratching the surface this only works because of ionic and this is a so-called web component it's a custom HTML element you can build those on your own as well and I got a course on that too if you are interested but here the ionic team built a couple of components for us we can just drop them into a page and use them and of course there's more than just a button you go back to those docs here and you actually go to components here at the top you see there are a couple of groups of components and you can click for example on the button and now here you got a detailed description of the button and there are way more components built in as you can tell here if i zoom out a bit here and reload I also get the side menu here it is and now you see there are a bunch of components built into ionic which you can use and the official Doc's are nice because you always have this preview on the right to see how does component look and works and you see detailed descriptions of how to use it for different frameworks or vanilla JavaScript and how to configure it which properties you can set which attributes you can set and so on so these Doc's are awesome and I will come back to them from time to time but for now we added our first button that's pretty amazing so we get this button here this standalone ionic element and we connected a click listener that's nice now let's add more because we got so many components here let's add more components and let's start building a very simple first application where we then can later also understand why we might want react in the equation I want to build a simple body mass calculator where we can basically calculate well our body mass index now in case you don't know this is the formula we can calculate the body mass index by dividing weight and kilograms by height squared in meters or if you're not using the metric system I can tell you one kilogram is 2.2 pounds and one meter is 3.2 eight feet so that's how we will be able to convert our different measures now that being said that's the formula that's what I want to build here now now that's far we just have a button not really what we need right now we certainly need two inputs to let the user enter a weight and a height and to keep things simple I'll start with the metric system we will adjust this to also allow for other inputs but for now let's start with the metric system you saw how you can convert values on the slide before and yeah with that let's build it so we need an input and if we scroll through the list of components we do see an iron input here this is an input element which you can add which can be styled and configured in different ways as you can tell and that looks just like what we need here so let's go back to our page here let's actually remove the button and the script and let's add a iron input opening and closing tag now on this iron input we can configure various things and if we switch this year to just JavaScript we also see that we can combine it with the iron label inside of iron item two basically give this input a label so maybe let's do this because we can then also configure the label to for example be floating above the input when we click into it so let's add an item which seems to be an aberrant provided by ionic and a die-in label and here I will add your height as a label and now I'll duplicate this to have a number I an item where I ask for the weight then I have another input now on both labels I will add position equals floating how do I know that I can add this well because of the official docs which I really recommend that you dive in from time to time because there you can see all possible configurations and what you can do so here we get the floating position we could also set it to fixed and you can see the different positions partly here in the preview and of course you can also just give it a try so here I added position floating and I'll do the same here on the weight if you save this and we go back to our little application and we reload we see these two inputs and we can click into them and they float and now here's also something very nice in the chrome dev tools and I would recommend that you use Chrome to follow along you can click on this icon here this will give you a preview of the web app as it will look like on a mobile phone in the browser so this is not a preview of the mobile app but of course it's really close this is how it would look like on a mobile device and therefore most likely also how it would look like once you build it for a mobile phone so here is how it would look like on a mobile device most likely now that's nice it's a good start we got our two inputs here but we're not really done there are more components but of course I don't just want to go for the docks together with you so we'll show you another very important component here there is an iron content component and you always have just one iron con component per page so per HTML document in this case and you should put your content into that if you do that and here I just press the prettier shortcut to format this and you reload you will not really see a difference this is just a good practice it's especially important if you then combine it with another component ionic ships with and that's the iron header you add this above your content and there you add a iron toolbar typically in which you add a iron title there you can now set a title which will be displayed on the screen for example BMI calculator this then all should be wrapped in an iron app and you only have one iron app element per page as well so you can probably see a theme here you have a header which you will see in a second is something that is on the top of the page and then you have the main content you could also add a footer but here we don't need one now if we safe that we go back just looks good now we get this header here and we can configure this a bit more you can go back and on this toolbar we can add a collar we can set this to primary now primary is one of the supported colors I will dive deeper into theming and styling in a separate module for now let's just add primary here like this and now if I reload this Hey now it has a blue background and this now really looks more ish already so we added these inputs with their floating labels we added this toolbar and we did all of that with all those nice stylings and effects by just adding a couple of HTML elements which are not really HTML elements but which are custom elements unlocked by ionic by this ionic framework we added deaths of course pretty pretty nice that's a first step now with that let's continue and let's make sure that we actually turns into a real BMI calculator where we really calculate the well body mass index of an individual so we get started with this body mass index and more importantly with our first ionic app therefore with just ionic no reactant will thus far now my goal is to add a button and when we click this button I want to output the body mass index off the user below the button here so let's add something new below our two items here and that's the ion button which we already saw before and there we could have a label of calculate and when we click this button I want to calculate that body mass index and I want to output it below this button and maybe here in a div and that's important this of course is now a regular HTML div because just because you're using those ionic elements those ionic components does not mean that you can't use regular HTML elements anymore you absolutely can and it is quite normal that you do so really don't get confused by this you can do this and here I'm adding a div with an ID of result because I want to be able to select that tip with JavaScript to then add an output the result inside of the dip once we got it after we clicked this button I will also give these inputs IDs so that we can easily select them by a JavaScript and read their values so here we got the height input let's say and there we have the weight input now with all of that it's time to add some script code and therefore I'll add an app dot J's file the name is totally up to you this is just a JavaScript file which I now will import here and I'll do that let's say here by adding a script source is app j/s and I will add the defer attribute here to make sure this only starts executing after the entire HTML file has been parsed in case you didn't know the fur before my complete JavaScript guide is the place to learn this and all about JavaScript so here I added this import now we can select the button to add a click listener select two inputs to get their values and then of course ultimately calculate a result once we get these input values to then output it down there let's do that next so in order to get started with all of that let's go to app J s and let's select a couple of things there D calculate button for example by using document where E is selector and then we can just select the first I on button we find because we happen to only have one eye and button in here so this is the button I'm interested in if we had multiple buttons we could of course add an ID to this button select two selected by that ID that's by the way something will do for the e2 inputs here we have our height input you can get this with document.getelementbyid e and then it's height input this is the ID which we added to this input and of course for the second input we can simply repeat this here and just select it by that different ID now we can add a little listener here to D calculate button click listener and after clicking this I want to execute a function which I'll store in a new well function you can't write it with the function keyword or create an arrow function which you store in a constant which is what I will do here I will name it calculate BMI and that's just an arrow function and that's the function I'll hook up to this click listener so that's really just regular JavaScript now in here I want to get the values which were entered into these two inputs so we got D let's say entered height by selecting the height input and they're simply the value property like this and we do the same for the entered weight by selecting the weight input here weight input whoops I should rename this up there too now here we know that we will definitely find elements with these IDs and they will be input elements if you didn't know that with certainty you might add a if check to check if height import a height input or weight input would be null but here we no they won't be because we have these elements on the page now we can get our BMI by making this calculation we want to work with numbers though and as you know what you select with the value property will always be a string so I will add a plus in front of that to convert the string to a number again we could of course check if that failed if we maybe got not a number as a result and technically that could happen in this application if the user entered anything but a number here but I will assume that we just enter Bella's data here of course you can add a check for some validation for simplicity I will omit it here and now the formula was weight divided by height squared so entered height times entered time's entered hide here in brackets so that this gets calculated first and then the result is taken to the wide entered weight by it and then for now I will just console lock that BMI to check whether it works we will assume I'll put it on the page but for now let's just do this back here let's reload and now we'll enter my height here in meters that's important so if you're not used to the metric system simply use Google to convert your height and weight to the metric system so two meters and kilograms and here are 178 tall and my weight is 70 not 80 72 and let's press calculate here and that doesn't look right simply yet because that should be the entered height here not weight had a little bug let's reload 1.78 72 and that looks way better that's my body mass index which is absolutely okay so with that we got this finished but of course this app has a lot of flaws we can't enter anything here and that will just lead to not a number being output we also don't output the result anywhere on the screen just in the console which is not optimal and of course styling alters maybe not where we want to have it and of course all is in addition this only works with the metric system we currently have no way of switching to let's say pounds and feet or anything like that so these are things where we can improve this before we do that however let's have a look behind the scenes all these ionic components because now we work with some of them which is nice how do they actually work under the hood though so we played around with some ionic elements we can work with them from inside JavaScript that's great but how do they actually work internally is this magic how do these web components work let's take that good old iron button with which we worked before as I said this is a web component unlocked by ionic by desire net framework you could build your own web components I have a course on that not all browsers support everything like this out of the box but ionic thankfully automatically loads a lot of polyfills which make web components work in a broad variety of browsers so that we can not just use this in Chrome but also in edge and in Firefox and Safari and so on so this is a HTML element which is unlocked by ionic in the end the ionic team created a bunch of web components with JavaScript HTML and CSS which we can just use and that's important I said it with HTML CSS and JavaScript this is how you could imagine that this button looks behind-the-scenes this is regular HTML with elements tags the browser knows in the end some CSS code for some styling here with some CSS variable which we haven't used thus far but which we will use for the course and maybe also some JavaScript code to do certain things behind the scenes now that's all code we could write on our own but it's all kind of packaged up in this one element and that's how you can think about these components in the end it's just code you could write on your own it's no magic it's just things building blocks the browser understands but it makes work easier for you because you don't have to write this HTML code you don't have to write this specific CSS code and you don't have to write maybe some extra JavaScript code which implements some behavior behind the scenes instead you got all this packaged up and you got a more powerful button then maybe the built in button which had no default styling and which maybe all select some other features who you now have with this ionic button now this packaging app also has a name uses a technology called the shadow Dom which is one of these features unlocked with those polyfills shadow Dom that's basically a feature built into browsers which allows you or in this case the ionic team to hide certain things away from your view and let the browser render it behind the scenes you can see that shadow Dom in the browser if we go to the elements tab and we for example select this button here is the iron button and there you see this shadow root now if you expand this you in the end see what the button does behind the scenes you see it uses a normal button element and you see it has a button native style which you didn't write but which the ionic team wrote so here you can see the styles which were applied by the ionic team and you see the HTML structure behind that button where you see there is a span and something called slots which we'll see in a second and much much more you don't have to write this on your own but of course it's always nice to know it so that's ionic behind the scenes and that's what we're working with here with that back to the SAP let's enhance it a little bit let's start by enhancing the way this looks a little bit I actually like it but there are a few things I'd like to improve for example I'd like to have some spacing around these inputs here and I want to have the button centered now there are various ways of doing that you could of course add your own classes for example your own CSS classes you can add those to HTML elements introduced by ionic as well so we could for example add inline styling or as I said a class here which we then style with CSS to Center all the text or to add some padding but we can also use certain features that are built into ionic already for example there are so-called utility classes these can be found found under guide here and then you go to layout CSS utilities there you find a couple of classes normal CSS classes which are also automatically loaded by ionic which are available everywhere which you can use for well some stylings you might want to use from time to time for a centering text or for adding some default amount of padding or margin so in our application here for example we could go to this iron content and add a class of iron padding here to add some padding to this application just by adding this class without writing any CSS code we now have a little bit of padding which I personally like now for this button here we could add a div here and then move this button into the dip so that on the dip we add the iron text Center utility class and you find all utility classes in the official Docs of course by doing that the button is centered now maybe we also want to have some margins we could add an iron margin here and this will add margin in all directions or we add iron margin top to add some extra margin to the top here like this I will actually add it in all directions so this is something we can do here now we automatically have a little bit of a nicer styling there also is a built in grid system which you could utilize if you also want to organize certain elements in a grid layout and maybe I want to do this I want to add a second button next to the first one which actually should allow us to reset the inputs and clear what's entered in the two inputs here for that I can of course add a reset button here but if we do that and I reload they are side by side but maybe I want to distribute them a bit differently that's where we can use that ionic grid for that of course we can look for that right here it is and you'll find a documentation of how it works it basically allows you to organize content in rows and columns and that's something you might know from our grid systems too for example from the bootstrap CSS library in the end you wrap your entire grid with the iron great element and then you can have rows and in every row you can have a couple of columns up to 12 columns you can also assign sizes to columns so that if you have less than 12 columns you can control how wide this specific column should be otherwise it will split the available space equally so back to our app that means that we could replace this div here with let's say the I and grid of course also the closing element and in there here I have one row and now in this row I have my two buttons but now every button gets its own column with the iron collar element and you'll find all these elements in the official Docs as you just saw so if we now do this and we save this they go back here and reload now this is distributed a bit nicer than before and of course you can also configure the grid you could make one column wider than the other you can change how they split the available space I am happy with this layout but definitely feel free to dive into those docks and play around with the different configurations you have for aligning the items and so on but now this looks nicer let's not make sure that the reset button all the works and that it actually resets these inputs definitely feel free to do this on your own in the next lecture we'll do it together and we'll then also add I can't do those buttons because I think having icons there would make a lot of sense so we got the grid let's now make sure the reset button does something before we add icons now for that I will give it an ID because now we have more than one button so we can't select this second button with the query selector and I'll name it reset button and to be consistent I'll also give the first button ID technically we could still select it with the curry selector because it is the first button on the page but anyways I will give it an ID that's D calc button lets it now back in JavaScript we can select this first button no longer with curry selector like this but with get element by ID and there it was the calc button and now we got also the reset button and there we can get it by ID and I named it to reset BTN that's the IDE I assigned there now with that added let's add a new function reset inputs may be like this and here all we have to do is reach out to the height input set the value equal to an empty string and do the same for the weight input here now we just need to wired it up by adding a listener at the bottom reset button add event listener and it's a click listener and listen to a click and point at the reset inputs function like this this is again just vanilla JavaScript but now if we go back to this application and I enter my height and my weight and for some reason I don't want to calculate I can press reset and this does not work well I should target the value here as well save that and reload and this looks better so now it resets this both and we got these two buttons working now as I said some icons would be nice so that we can also see a bit quicker what each button does but when it comes to icons we have a component for that we have the iron icon component but this is a bit special you click on it we're taken to ionic and calm it's still part of ionic it's loaded automatically in an ionic project or in our case with these ionic imports we add it but it wouldn't be uncommon for you to use ionic ons outside of ionic projects as well you can add those ionic components to any project you want after all now here you get a bunch of icons and here for example we could search for a calculator to find a fitting icon like this one and now click on it and now at the bottom we see the code we can use to add this icon and thanks to these ionic imports which we have here we can't just add it like this and we don't need to do anything else now we can add this in here instead of this iron button there besides this calculate text we can add the iron icon and if we save this and we go back and we reload we get the calculator here now that's okay but but it's a bit close to the text maybe now that's where we can use an ever concept web component support and which is therefore utilized by ionic we can use slots slots allow us to control where insert offer components something should be output and ionic uses this internally to offer us different slots we can use an abutment control wherein the button exactly this should be output now by default it's all in the central defaults slot but we could assign a different slot to the icon just by adding the slot attribute and the surrounding element will then take advantage of this and here for example we have the start slot now to see which slots are supported the official docks are your friend there if you go to the button component you will see a slots area and any component that has slots will have such an area in the docks and there you see these slots you could target and there is the start slot now with that start slot I can save this file reload and now you see this looks nicer now let's do the same for a reset of course feel free to do it on your own first I will search for reset here and yeah I like this icon so again we can just wrap this here go back to our page go back to our code and instead of the button next to our text here I will add this icon and again use the start slot to make sure this icon is positioned nicely if you do that and we reload now here's the reset icon so that's decent that's great we also can change the look of the button a little bit we go back to the button docks here by changing its fill mode you see we can assign a fill attribute and we can set it to default or actually as you might guess this is the default you don't need to set this but you can change it to clear or outline for example and to see what this does let's just try it by the way that's in general a good strategy if you are not sure what something does or what some attribute does just give it a try you can't break it you can always undo it if you're not happy with the result so here on this button on the button not on the icon that's important on the button I can add the fill attribute and for example set this to outline now we can again save this and go back to our page and now this button looks different and that really is the power of ionic and web components you can easily configure things and change things there we got these buttons in place that's nice of course we still got no validation but that's ok but now we get a decent looking app here now as a final step here before we finally combine this all with react which is ultimately why we're all here right before we do that as a final step let's actually improve this a little bit by now finally outputting the result below the buttons instead of in the console so finally let's use this diff here this resulted let's actually maybe all's use that into our grid here in a separate row and one column which then automatically will span the entire width of the row and now here inside of that div I want to output my result actually since it is now in this column I can give this column here an ID I'll press alt and get rid of that there because as you already saw we can target these elements these ionic components with regular JavaScript so since I only need this as you could say a hook to output something to render a new element we can absolutely use it like this now in apt Reyes in calculate BMI instead of console logging dpi BMI like this I want to output it now first of all I'll check if this BMI is not a number in this case I just want to return here and not continue with the function execution so that we don't output anything if it's not a number we could also throw an alert here and say not a number please check inputs this will be a regular browser alert by the way not an eye on your alert we'll learn about those as well but later in the course so now we get this if we don't have not a number so if we have a number if we have a hopefully valid result we want to output it for this let's select this result area by its ID you're all named is result area maybe with document.getelementbyid e result and in there I want to render a new element now for that we can create a new element the result element with document create element not attribute create element and then here I want to create a I and card and yes you can do that you can create ionic web components with JavaScript you cannot just add into HTML you can create them like this the iron card is an element built into ionic here it is it gives you this card look we could add images and so on but we don't need this year I want to instead create such a card and in that card I said we want to output my ayan card counted element which holds the result so Judas result element to this card which is therefore I'll set the innerhtml to template literal string here so that I can easily inject dynamic content here and also write this as a multi-line string string to make it easier to read and there we can add the iron card content element and also close it iron card content so that's that element here in there I want to have let's say a h2 tip and all to close this h2 tag of course and in there we can now inject something with this syntax and this by the way is regular JavaScript syntax it's called template literal and we're template string although you can look it up if you don't know it attached you find a link to more information about this and in my complete JavaScript course for example you learn about this as well so this is how we can inject the value of a variable or of an expression in general into this string here and here I want to inject DB mi value so this is output in the card content which is part of this card because I set it as the inner HTML of this card and now we just need to reach out to the result area and there I want you add this new element for example with append child result element I also want to make sure that may be any existing elements I had in there are cleared first so I'll reach out to the result area and set inner HTML to an empty string so that it has no HTML content and then I add this child of course there are different ways of doing that but this should be a pretty straightforward understandable way of rendering a HTML element dynamically with some dynamic content with all that we can go back to our application reload enter our values again click calculate and here's our card and if I change something here for example I changed my height we can calculate this again of course we can also reset this the card is not deleted you could add this logic but it's still here but the inputs are clear and if I calculates again I get a warning here because I get not a number so this is all working we're now also dynamically creating an element here which of course also is quite nice to have however we have missing features for example here we're not supporting the non-metric system so feet and inches and we can maybe already also see why using a library like react or some JavaScript framework might be interesting because we wrote a lot of JavaScript code here and that's of course kind of the idea about JavaScript heavy front and app but we're already writing some code which we normally don't really want to write as a JavaScript developer here when we interact with the Dom to add an element and clear content this is the kind of code we don't we want to write we use libraries like react to define the goal and to focus on our core business logic like this calculation here because that's where the value of our application really comes from the technical interaction with the document that's really something we don't want to work on it's easy to introduce errors here or to write code which is not that performant like here will be always clear the existing content that might be unnecessary to do so we can easily mess up code here but we also want to just focus on this code so we can use a library like react to take away this part here and let react handle this let react interact with the Dom so that we can focus on the core business logic that's why we use react in normal web apps and then the enters is just a normal web app a normal web app will be all zeros ionic so therefore before we have a look at capacitor and what we can do with that and how we can get a native mobile app let's actually continue with this web app for the moment and let's at react to it let's rebuild us with react that ionic to see how that works how react helps us how we use ionic and react and then thereafter calls use capacitor to turn this into our first native mobile app not the last one in the course the first one so now did we started at playing around with ionic and we built this first very simple application with just ionic components and vanilla JavaScript just so that you could get a feeling for how you generally work with ionic it's now of course time to make the next step because this is an ionic react course so in this module we will now introduce react to the equation we will make sure that we actually built this application with not just ionic but with ionic and react and therefore we reap all the benefits libraries like react give us and of course in this course react in general gives us so in this module we will see how we can create a react and ionic project so that we can get started writing code right away we'll then see how we work with ionic components in react projects and how we write react code in general in react ionic applications and we'll also have a look at a few components we haven't seen before and in general throughout the course will of course see more and more components but especially important we'll have a look at overlay components and you will see how you actually work with those in react and ionic and how you can easily make sure that you for example show an alert to the user a more beautiful alert than the built in browser one and so on so let's get started and to get started we can go back to the official documentation and there you can go to installation CLI installation because now we're going to use this command line interface the ionic team created for us to create and manage projects now for that we need to install it and we'll install it with a tool called NPM which stands for node package manager now chances are you know this tool because basic react knowledge was a prerequisite and you typically create react projects with help of NPM as well in case you don't NPM stands for a node package manager and it is a tool that is distributed together with node J s now node J s is a JavaScript runtime that allows you to run JavaScript outside of the browser and you could use nodejs to for example build server-side applications with JavaScript now that's not what we'll do in this course because this course is about building front ends with react and ionic but nonetheless we will need no trace for two reasons one reason is this NPM tool does node package manager tool which allows us to install dependencies like this ionic CLI so it's basically a tool that helps us install stuff but in addition we will also need note J s itself even though we're not going to write any node JS code because it will turn out that the react project we create behind the scenes will use no trace to bring up a development server which we can use to test our application so simply go to node.js org and download the latest version of nodejs there whatever version that is when you're viewing this video so here you can just click this button you will get a normal installer you can walk through that installer install nodejs and you will automatically get this npm tool as well once you did that you're ready to run this command so let's do this simply open up your normal terminal or command prompt you can use it on all operating systems and paste it in now one important note on Mac OS and Linux you might be getting a permission error if you run it like this if you do add sudo in front of that on Windows you don't need to do that and there it also won't work sudo is not a support command there and this will ensure that this runs fine you might be prompted for your password so if you are just enter your system password and now this will install this ionic CLI as a globally available tool on your operating system once you installed it you can use that tool to run some commands and now make sure you navigate into a folder with this CD command where you want to create your ionic react project now I already am in such a folder and therefore I will now run ionic start and this is a command which allows you to create a new project so I'll just enter here and now here I'm asked whether I want to use angular or react over time you might see more options here but of course I will go for react here I also do have an ionic angular course if you're an angular developer but since you took this course you probably are not or at least not exclusively and therefore I will choose react now next we need to assign a name and I'll just name it ionic - react hit enter and now you've got a couple of starter templates to choose from you could for example start with an application that automatically uses tab navigation but we will add the step-by-step on our own so that we can see how it works behind the scenes and hence we'll just start with the blank template here so choose blank with the arrow keys and hit enter and now you can last but not least answer whether you want to integrate your new app with capacitor and for the moment you can choose no here we can change this later and we will for the moment we'll just build an ionic react app without capacitor but we will add it later so choose n for no here and hit enter and this will now create a new project and set everything up such that you can write your ionic react code in there so let's wait for this process to finish and here we are now you already see some instructions here at the bottom we can now see D into D created project in my case into the ionic react folder because that's the name I chose and in there we can run ionic serve to bring up a development server which hosts our front-end our application on a local host address which we can use for testing the application so will not be clicking on some HTML file anymore but instead we'll use this hosted dummy application I'm not going to do that here however instead let me open that folder with visuals to do code with this IDE I already showed before and here it is now inside of that project in Visual Studio code I can go to terminal new terminal and open up such a terminal here and that's your normal system terminal or command prompt just integrated into this IDE and here we can now run ionic surf and bring up that development server with this way the difference is that now I got this running server here integrated in my IDE and if we ever should get any errors being output there we can immediately see it whilst writing code instead of having to check a separate terminal running somewhere else that's why I'm using this integrated approach now this process which I started here will keep on running and you should keep it running as long as you are working on your project as long as you are writing code because it will also watch your files and whenever you change something it will automatically rebuild this application behind the scenes and reload the hosted web app in your browser and speaking of that it should have opened up a new tab in your browser if it didn't you can manually go there under localhost 8100 and there you should see this dummy application running this simple application where you got a toolbar at the top and some content in the middle of the page and I'll open up the browser developer tools and go back to this mobile preview mode here which I already showed you earlier but of course that's optional you can also stick to the browser window to the normal one so with that we got our first ionic react app this dummy app we got for a by using the ionic CLI and now we can explore what we have in our project folder it's certainly more than just a HTML file and a script file but you should already know that from regular react apps because you know that you write code in a very modern way with your code split across multiple files using features like JSX and react and then you got this development workflow this development server also where everything is bundled up and optimized and then served in your application here and so that you can preview it so the actual code we write here is actually in the source folder and the public folder also is important because that's the single page we're working with we don't really need to touch this a lot occasionally we will visit it but this is in the end a single HTML page which will be served as part of your application and where the entire bundled-up script code which we write here in the source folder will be hosted in now with that let's close public we also got some configuration files here package dot JSON for all the dependencies were using in the project this will grow over time when we add more dependencies ionic conflict for a some ionic configuration we don't need to touch this at the moment and the TS conflict or Chasen fall and you might not be used to that you also might see something strange if you open the source folder because in there we got a components folder we might know that a page is folder ok maybe you saw that before as well but then we got dot T as X Files and that's strange you might be used to working with dot jeaious or dot JS x files and if you open such a file you see some familiar things imports like this where we import react but then if we scroll down this is strange this colon after app with this thing I mean this is an arrow function where we returns up JSX code these probably are some ionic components they look different that before but yeah maybe that's just how it has to look I'll come back to that but what's this colon thing here why are we working in dot T as X Files here is one important thing when working with react and ionic you typically use typescript for your react application and that is something you might not be used to because normally in react development you work with JavaScript now you can absolutely use typescript with react even if you're not using ionic but you don't see that as often as you see react with JavaScript however ionic react projects use typescript by default and whilst you could change this which is kind of tricky or requires some manual wiring up work I recommend that you stick to typescript no worries it's easy to learn and you will learn it in this course so I will teach you what you need to know along the way nonetheless if you like it and if you want to know more about it I get a complete typescript course which you can also check out to learn all about typescript and also more about typescript and react in there typescript is just a superset to JavaScript which adds extra features to the JavaScript language for example types static types so that you can add type safety to JavaScript and typescript is a language which doesn't run like this in the browser instead it needs to be compiled back to JavaScript and this whole compilation process is already included in this project setup it happens behind the scenes and the tears conflict or JSON file in the end is the file where this compilation process is configured now if you know what you're doing you can find Huhn this to your requirements but the default setup is absolutely fine and you don't need to change anything in there in the end the code we write here is very familiar to the JavaScript code you already know you can add some extra features with the help of typescript to write better and less error-prone code and it automatically is compiled down to JavaScript and bundled up by that development workflow which is running behind the scenes with the help of ionic serve so that is how you have to think about that other than that this is a regular react application where we have a react component which returns some JSX where we have a couple of imports these are all just CSS imports to wire up the different styling things that we need in a ionic application before we had CDN links now we have to import everything manually here and you should just leave these imports and we have our index tech TSX file where the entire application component the root component is mounted to the Dom with react on render here so this is how this works really just what you already know just with this twist of using this extra language typescript now in order to get started writing some code let's first do some cleanup work here and remove some files and code which we don't need at the moment for example here I will remove this Service Worker unregister thing remove this import add a new line here to make this a bit cleaner remove setup tests because we're not going to write any tests here so I will remove the file we don't need it we could remove the Service Worker file I will leave it here for the moment but you could remove it in app tsx I also want to clean up this router stuff I will remove the iron router outlet import I will remove this import from ionic reactor outer we will add routing later but for the moment we don't need it I will also remove this import from react router Dom I will leave the other imports here leave all the CSS imports and in here just return I an app and in there maybe just a h2 tag where we say this works and we'll add more useful content soon the theme folder holds some styling we'll have a whole module about that for the moment we can ignore it the pages folder has two components which we now don't need anymore so we can remove the pages folder that means that an app tsx we can now also get rid of that home import here so that we only have these two imports left we can remove the app dot test tsx file since again we're not going to write any tests and in components I will also remove all the files there you can always remove the entire components folder for the thereafter I will restart the psionic serve process and save all files and now we have a cleaned-up project where we can gradually build up our app from scratch you also find this cleaned up snapshot attached to this lecture so that we can all start from the same starting point if you now reload your application here in this low closed 8100 browser you can also remove that home segment and the URL you should just see this works here and this is now where we will start and where we will now migrate our project we built before to this ionic react setup so we got this cleaned up project and then before we actually started writing some real ionic react code let me give you a brief introduction to typescript in case you already know typescript and you know how react works with typescript you can of course just skip this lecture this here is a type assignment and it's the most important thing typescript adds as I said typescript is a superset to JavaScript you could translate this with it's an extension of JavaScript it adds new features to the JavaScript language and the most important feature that it adds is the feature of static types which means that whereas you have dynamic types in vanilla JavaScript you now have to define or you can define types in advance so for example here we are defining the type of app a type assignment is always done by adding a colon and thereafter the type the thing in front of the colon should have so here we're saying this app constant should hold a value of this type now what is this type though this is a type coming from react in the end so with react dot we're accessing the F C type in there and that's simply coming from our react type packet which already was installed for us here in package.json you can see it it's this types package which basically adds type definitions to the react library you could say those packages exist for all major libraries and we're saying okay this constant app should hold a react FC type now this actually stands for functional component and again it is a type predefined in this special types package which already was added to this project by ionic start by this command we used to create the project this is simply one of the built-in types which is provided by this types package now it defines that whatever we store inside of app has to be a valid functional component and what is a valid functional component well it has to be a function of course and it has to be a function that returns JSX and that's just what this function here does that's why it fulfills this requirement if I would temporarily cut this and for example store a string in there I get an error as you can tell now normally without this type assignment this would be valid JavaScript code right it would not work in a react a bit would not bring something to the screen but from a pure JavaScript code perspective this without the type assignment here so like this would be valid JavaScript code it would just be a string stored in a constant with that type assignment however it becomes invalid not in JavaScript world because JavaScript doesn't know these types but in typescript world and as I mentioned the typescript code will be compiled to JavaScript and during this compilation process the typescript compiler will check for errors like this and Visual Studio code is actually a typescript aware IDE which is why we already see that error in the IDE even before compiling the compilation would only happen once I save this now it is rebuild it compiles as you can tell and normally you should see the error down there unfortunately this is a bit buggy and therefore it's not showing the error down there but we still see it in the IDE here we see that the type hello so this text basically is not assignable to the type functional component so we have to revert this to bring back our functional component to have a valid code snippet here and this is the feature typescript adds now of course you can add types everywhere not just on constants that hold functional components and of course there also are more types than this functional component type there for example also are some default types like the string type with this I would be saying that title only hold a string and then here I did store a string so this is valid my IDE here only compare complaints because I'm never using this value but from a type perspective this is correct if I would use to build a number type instead and string and number and boolean are default types typescript chips with then I would be getting an error again because this clearly is not a number so this is the idea behind typescript again you can take my types of course to learn more about it otherwise I will teach it here along the way step by step now of course we need no title here we only need this functional component and there I do return this I and app I mentioned that we have one I an app component per application if you remember and in there I have a regular h2 tag now since I introduced you to typescript let's now move on to using ionic in this react typescript application how does that work and how can we get closer to this ionic application we already built before we got the ion app component here and if you compare this to the ionic app we built before in the module before this module you might notice an important difference here I in app looks like this we have this notation where we have starting capital characters and only one word without a dash whereas before we use these components which look much more like regular HTML elements now we use this syntax here in ionic react because we're not writing normal HTML code here but we are using JSX code here and it turns out that JSX doesn't support web components like this out of the box you need some fine-tuning there and that's some fine tuning the ionic react him already did for us if we scroll to the top of this app TSX file we actually see that we're importing iron app from @ ionic slash react that's important we're importing this this turns out to be a react component which we therefore of course can use like we can use our custom components in the JSX code so these HTML components which we can also use like h2 there we really can only use the default HTML ones not the web components unlocked by ionic those ionic components have to be imported from @ ionic react just like we're importing our own components from our files you could say this simply has technical reasons in react and the ionic reactant gives us this ionic react back edge where we in the end have these wrapper react components which wrap these ionic web components and wire them up behind the scenes so did what we us behind the scenes is still this we're still using the regular ionic web components but we got this react component wrapper for all those components where we then just work with those react components in our JSX code now the translation from this to this of course is easy you omit the - and you start every word in a word with a capital character so I an app written like this all lowercase with a dash becomes this without a dash where the I and da are in capital case and dad will hold for all those ionic web components the important difference here between react components and ionic components is that react components of quartz are created with the react library they are typically created as functional or class-based components and you use JSX there to define what react should render to the Dom in the end and of course they're only usable in set of react apps are you on a gaps on the other hand are these pre-built web components built with vanilla JavaScript following browser standards they use native web technologies therefore and they can be used anywhere but the react library is a bit picky about this a bit special and therefore in order to use web components there some wire up work needs to be done and that's the work the ionic team did for us when it created that ionic react wrapper this wrapper in the end just makes sure that these ionic web components which is provided by the ionic core package are actually wrapped into a react component and those wrapped components are then provided by ionic react so we'll only work with these wrapped react components which under the hood use the normal eye on ik web components but we'll work with these wrapped ones for technical reasons now besides these technical reasons we also get a better development experience with these custom components we get better Auto completion for example certain react features are unlocked with that are wired up behind the scenes and in general it does this technical work I already refer to I just highlight this so that you know why now all of a sudden the components look different behind the scenes were still working with the web components just wrapped by the ionic team and exposed in the ionic react library so with that all out of the way let's now actually write our application here and to get started I just want to pour it this old application here which we wrote with just ionic and JavaScript to react now for that we of course need two things in this iron app and that's our iron header opening and closing and also our iron content opening and closing now important we can't just use these components like this we need to import them and that's really important you will need to import all the ionic components you want to use inside of a react component from at ionic react so here we need the iron header and the iron content now Visual Studio code actually will automatically add these imports if you press ENTER at the right point of time but here I wanted to show you that you need these import now in the iron header we can add a ion toolbar and now that's what I meant once visual studio code suggests this you can hit enter and if you do that this import should have been added automatically by visual studio code if that's not the case you need to add it manually so we need the I and toolbar and in there we have our iron title like this again I hit enter tap by the way all the works to automatically add this import now in this title we had BMI calculator so we can just copy that move it over there and put that between our title tags and now in the content there we got our two iron items and then we got this grid actually here I will move everything into the grid technically not required but I feel like doing this so I will add the iron grid again hits tap to automatically at the import with the iron row here and in there I am column and now in that iron column here I will add this iron item so we have an iron item here with the I and label and then below that are I and input and I'm constantly hitting tab or entry here if you don't do that add all these imports manually you see this is also getting very long here so that's a great place to hit this format document shortcut so that this is split across mountains and easier to read with that let's go back down there and then on this first input I had your height as a label so let's copy that into here let's add this position attribute and that's now where you see this improve development experience I was referring to we get auto completion here thanks to react and typescript and you see there is a position prop and once you add the equal sign and the quotes you should automatically get those suggestions here regarding the valid values you can fill in and that's of course amazing because it often saves you a trip to the docs to find out which values you can use here we just see it in the IDE if you don't get this by the way you can't try pressing controlled space and you should also open this auto suggestions menu so here I'll pick floating so with that we got the height added now I will copy this and add another item here we have your weight side note I don't add this ID which we had on the input because I'll get that value from the input differently now we're using react and also one important thing I will actually grab this iron item and not edit in the same column and row but instead add a new row and a new iron column and add my new item with the second and put there just to really use this grid correctly where we should well work with rows and columns in the way that makes sense we have two inputs that should be in separate rows so of course in a grid they also should be in separate rows so that's that now I did have iron padding on the content I still want that so on the iron content here we add a CSS class but since we're in react not with class but with class name and that has nothing to with I on or with typescript this is regular react so we add class name and then I and padding here to add this padding to this entire Content area now let's continue working on this we now also get these two buttons so below the inputs we add a new row with a new column here and you column and in this column I'll add a button of course here again make sure you add the import or you press tab or enter correctly for the IDE to add the import and in this button you might remember we had this icon so again we use I an icon here like this we can use this as a self closing tag because there will be nothing between the opening and closing tag and then here we had a name of calculator outline so I'll copy that and add this here and next to this I have to calculate label now I'll copy the entire column and add it as a second column next to the first one and here we had reset and the Refresh outline I can here so here I will use refresh outline and reset and use those slots that's also supported and react because again these react components are just wrappers so here we can add slot and set this to start here we don't get auto completion here because the IDE doesn't really understand that this belongs to these slots of the outer elements so it can't predict which values are allowed by the outer element so that's something we'll have to look up in the docs and we do this here as well again I will omit all IDs for now I will also omit the text centering for the moment instead on this first column here I will add iron text left and on the second one I and text right to have a bigger distance between these two buttons but dad's ultimately totally up to you with that we're getting closer to our final result now we just need a row in a column for the result we want to render so let's add I on row and I and column and again here I will not add this ID because we will output this result card which we previously created programmatically with JavaScript differently now that we're using react because the whole idea behind react really is that we use this declarative approach where we defined a JSX code that should be output and then we can define different conditions when something should be rendered and react will be responsible for figuring out the way to get there and for doing the steps to bring something onto the screen or remove it from there so we can save this now and here i will restart ionic surf because it crashed before wait for this to restart and back in the browser if i reload here we have this look now one important thing we can see right away the icons are missing right we get a wording regarding that as well there's one important thing you have to know about using icons in an ionic reactor project you don't use them with the name attribute as you do it in a regular ionic project but instead differently instead of using that name you use the icon attribute the eye can prop we should say in react which we can set here and we don't set this to a string to a name or to some text instead we set a dynamic value here hence we need single curly braces to inject something dynamic here and the thing we're injecting is something we import from an extra package we import something from ionic ins slash icons this is an extra package which is installed by default you see it in the package to JSON file here this and this basically gives us all these icons available in this application and we just have to import those which we want to use in this specific component now here we had that calculator outline icon and you will see that from there you can import calculator outline now written like this in camel case we will also need the Refresh outline so we can already import this icon as well so these are the two icons we are importing here and now down there only icon components we point at calculate outline here and on this second icon we have icon equals refresh outline just like this and that's just one pattern you have to memorize in ionic react this is how you use icons and if we now save that it rebuilds and now you see those icons here this now visually is pretty close to what we had before color is missing the toolbar and the logic is missing so that's what we'll do next of course feel free to do this on your own because all you'll need here is really just default react knowledge will now do this like we would always do it and react but of course we'll do it together in the next lecture so where are you successful let's do this together for that back in our code we got to do a couple of things we have to wire up those buttons to functions and then those functions we need to interact with the data entered by the user to either clear these inputs or to calculate a result now for that we'll do this like we would always do it in a react app side note here in this course I will only work with functional components and react hooks I do teach that and also the other approach with class-based components in my react the complete guide course but again I will focus on this functional components with hooks style here so if you're not fully sure about that make sure you first pick up the dedicated sections in my react course or some other resources where you learn about that that being said here we are in a functional component and now we first of all need to define two extra functions functions inside of this react functional component function which we can bind to our buttons we have to calculate BMI function and I will define it as an arrow function here and we have the reset inputs function now you can already tell my ID is not too happy and the reason for that is that now this previously was just a arrow function where I returned just a JSX code now I'm adding more stuff to the function body so we have to change the signature of this functional component arrow function instead of a bracket which just wraps the return value we now add a curly brace and we add a closing curly brace to wrap our function body and now this J's Xcode has to be a return so we add a return statement here and to support multi-line code we wrap this into brackets now and then we can press the autoformat shortcut now that's working now we got these two functions here now we can wire up those functions and we do that just as we would always do it and react here on this first button we want to wire up the calculate BMI function we add the on click prop for that Dion click prop is available on the default button component it's also available on the I on button and you can see this in the official Docs of course all is it but also here with the auto completion basically all those default button props are forwarded here to the iron button so we can add on click and point at D calculate BMI function important just pointed it don't execute it here because we want to store the function itself this function object in the on click prop so to say we want to pass on that function object to the on click prop so that react and the browser can invoke this function for us when a click happens if we would add parentheses here the function would be executed right away when this code is parsed and the return value of the function here of this function execution would be passed to on click that's not what we want we want to pass the function itself that's also do this on the second button here and point this at the reset inputs function again just at the function not at the result of the function execution that's the first step now we need to get the values the user entered in the input there are various ways we could set up two-way binding where we listen to changes to the input and store the entered value in a state or we use refs a concept available in react and that's what I'll do to use refs in functional components we need to import a hook from react by adding this import here and that's the use ref fog it's written like this use ref and this allows us to set up a ref again that's just a react concept which I expect you to know it has nothing to do with ionic or with typescript refs are a react concept and with the use ref hook you can set up refs in functional components so we create two rafts here wait input ref with use wrath here and a second one with height input ref with use wrath and these refs can be assigned to elements in the JSX code so that we kind of establish a connection to those elements and we can retrieve values somewhere else in our JavaScript code with help off those rafts for that let's go down to that first input which is the height input and there we now add the ref prop which is available and we point that at the height input ref and then here on that second input we add the ref prop and pointers at the weight input ref now here I'm getting an error and this is now an error which we're only getting because we're using typescript it's a pretty long tryptic error but we see that the expected type comes from property ref which is declared here blah blah blah now that's just something you have to be aware over you have to know when using typescript which is why I'm telling you it here use ref like this creates such a ref object but typescript doesn't really understand what this reference will point at once we use it here in this line when the ref is created typescript has no chance of knowing that this eventually will be connected to this input down there and therefore when we do is so down there typescript basically says well this height input ref I didn't know that it should be connected here and hence when you use it up here I won't be able to support you correctly so we have to let typescript know to which kind of element will eventually connect this wrath and we do so by using a special typescript syntax we add angle brackets after use ref and between them we add HTML iron input element now what's that the angle brackets can be used because use ref supports so-called generic types does essentially means that the type of data the referee we're creating here is off is flexible it's not set in stone we could also store something like a string or a number or an array in a ref it doesn't have to be a Dom element but even if it is a Dom element it's flexible regarding which kind of Dom element and here we're saying well this ref will eventually hold a pointer at a iron input element and this HTML iron input element thing here this is just a type script type provided by ionic we don't need to import it from anywhere it's globally available it's a core type which is available when we work with ionic and typescript you could say and this now let's type know that this ref which is created here will eventually point at ion input element now still types wouldn't be happy because initially when we created so when this exact line here line 39 and line 40 when these lines are parsed of course no connection has been established yet that's why we also have to set a default value for this ref which is null which means initially it's not set to anything but eventually it will point at a iron input element this is what we're saying with this syntax here now what does this tell typescript it tells typescript that eventually this reference object will point at an object of type HTML ion input element which is just the underlying typescript type this iron input object which is created in the end has we also tell typescript that the initial value is null because at the start of this function execution of course no connection has been established yet now once this return statement has been executed these connections have been set up with the help of the ref keyword and then everything is fine because then types could also knows that the referee using here the height input ref is actually configured to be connected to a high and input element which is just what we're connecting it to here I know that this can be tricky to wrap your head around to be honest it's thankfully one of the most complex things when it comes to react with typescript and we already get this out of the way now as a rule of thumb you can just memorize that if you're working with refs and you're using them to connect to a element in your JSX code you have to set up which kind of element you'll be connecting to and initialize them to null and that's basically it with that we set up the connection to the height and the weight input ref and now here in calculate BMI we can extract our two values we can get the entered weight by accessing weight input ref and now here dot current dot value and do the same here for the entered height and you might have seen that there was something inserted by my IDE when I typed value this question mark now why was this question mark added here this is a special typescript certainty X which in the end is a shorter form available in typescript for writing a ternary expression where we first of all which check whoever weight input ref current holds a non null value before we then try to access the value property now why would we need such a ternary expression normally well because of course current could point at a null ref right initially the ref holds null as a value we set this up in lines 39 and 40 now of course we as a developer we know that calculate BMI this function will only run after the connection to the real Dom elements has been established in our JSX code but typescript can't know that it doesn't know that this code necessarily runs at a point of time where the references will not be null that's why typescript would want us to add such a ternary expression to rule out potential runtime errors when we try to access the value property on null where this would indeed crash at runtime now that's why we need a ternary expression and using this question mark syntax it's just a shorthand form where typescript will check whether current holds a non null object and only if it does types could we'll access the value property so in the end it's a shortened form of this longer ternary expression and the scenes once the types of code is compiled to JavaScript it most likely is expanded to a full ternary expression so it's really just a shorter syntax available in typescript if you know with certainty that by the time this is going to execute this connection will be established and this will not be null you can replace the quests mark with an exclamation mark this tells typescript this will never be null you can always access the value I guarantee it and we can safely do this here because we're writing this code and we know this function will never execute without the connections between the refs and our JSX code being established so we know we'll always be able to access our ref and extract the value hence you can add the exclamation mark and as a result the value returned by this will never be null it might be an empty string if the user didn't enter something but it will never be null this is just some typescript specialty which adds extra safety and avoids unwanted errors where you have to be really clear about your code and how it's going to execute and you deliberately have to tell typescript I'm sure this will always be set which forces you to reflect about your code and maybe fix eventual box you might have introduced here everything is fine we know this will never be null we can always safely extract this value move that we got the entered weight we got the entered height and now we can calculate a BMI by dividing the entered weight by entered height times entered height and we face the next problem and that's really the good thing about typescript it warns us early about problems and what's the problem here well if we hover over it we see that this must be of type any number or big integer or an enum type whatever that is but this actually is a string we have to add a plus here to convert this back to a number but now we're getting an error up here that this is possibly now now I said that this exclamation mark means it can never be now but the problem is it means that this connection with the reference will never be now the extracted value still could be now we can add another exclamation mark here to basically tell typescript that this also will never be null however we can't guarantee that it might end up to be null or actually an empty string in which case we would also have a problem so I will switch to a different solution here and check if entered height is falsey by adding an exclamation mark in front of it or if entered weight is false e and that will be true if it's null or if it's an empty string then I'll return so we'll only continue with the function execution when entered height and entered weight are not null and are not empty strings these two conditions have to be met only if it's not an empty string and not null we'll make it to this line and then I will convert these inputs here to numbers down there by adding a plus in front of them now it could still be a string like hello that's something we're not catching here but it certainly won't be now and with all of that let's console lock the BMI here for the moment to output it let's also implement the reset inputs function and clear these inputs for that we can again use our refs so we can again use the weight input ref current and set value equal to an empty string and repeat that for the height input ref now again we're getting an error for the same reason X explained before type scope doesn't know if that code could run without a connection being established and T reference pointing at a real object and therefore we have to tell typescript that this will never be null by adding an exclamation mark we're telling typescript this code will never run without a valid object being stored in this reference this will always be the case when this code runs and we can guarantee this to five script because we're writing our own code we know that the only way the reset inputs function runs is by clicking that button and that can only happen after this JSX code has been parsed and therefore after this connection has been established so there is no way for this function to run without an established connection and therefore without a valid value stored in the reference now you might be wondering after all these exclamation marks and question marks why is it so important to typescript that this is not now that wait input ref current is not a null object well it is so important because if it would be null and we would try to ax of al you property as we're doing it here on null we would get a runtime error right that's how JavaScript works accessing a property on null or undefined gives you a runtime error typescript wants to prevent us from such errors and that's why it's pointing us at all these code snippets that could potentially cause such a runtime error if something would be null now as I said we as a developer the way we wrote this code we know this can't be now we know reset inputs is only going to run after the J's X code has been parsed and this ref object has been set to the input element we as a developer notice typescript doesn't know it it doesn't understand enough about our program to notice so that's why we as a programmer can convince typescript that we know better by in this case adding the exclamation marks here which basically tells typescript don't worry I'm sure current will never yield null it will always yield a valid object this is why typescript ustus and why we add this exclamation mark and so on so with that we're clearing this and now finally if we save that we go back to our application and I enter values here I can click calculate and I see my result here in the dev tools and I can click reset and it resets so that all works however now you see when I tried a second time I get not a number here we'll have to fix that and in general we'll have to fix some minor issues here the problem was that I added a comma instead of a dot so we're not fully there but we got started and we're now calculating this in a react way with the help of refs and with the help of typescript with these extra things you have to watch out for when it comes to ensuring that you're not working with a null value or with invalid values in general with typescript you simply have to be more explicit about the code you're writing your intention and you have to rule out that your code runs in certain cases when a certain value might not be set and you would be getting a runtime error if you try to for example retrieve value on a null object that's why you have to reflect about this and deliberately tell typescript that this will never be null which forces you as a developer to really check your code and ensure that you're right about this statement and that this code can't run without an established connection through the ref and in this case this code should be fine now let's focus on the next steps so we are retrieving our values we are calculating a body mass index now let's continue working on this application and for that I don't just want to lock the body mass index here but just as before I want to output it below our inputs here now previously in the app where we didn't use react we did that by manually creating on card element setting its inner HTML content and adding this to the Dom now one of the big reasons why we are using libraries like react is that we don't want to do that we don't want to write those manual instructions instead we want to let react figure that out and just to find a result the goal reacts job is to find out the way to reach that goal so here translated to react that means that here in this iron column we want to eventually render a iron card so we can add this and hit tab to automatically add this import and in there we want to for iron card content with that h2 tag in there and that h2 tag should hold the calculated body mass index if we have one so for that we need state we need to be able to change the data in this component dynamically and reflect those changes in our JSX code and therefore in the Dom and that's where we need state and react in functional components you can manage state with the use state hook so let's import use state here and then in the functional component here we can call use state and the state I want to manage here is to calculate at body mass index and initially I said no value here because initially that's just undefined now you know that use State returns an array with exactly two elements so we can use array destructuring to get those elements out of the returned array and the first element is always the current state snapshot for this render cycle so to say for this function execution and here that would be our calculated BMI for example you can name it however you want and then the second array element which we extract is a function that allows us to update that state and therefore you typically name it set calculate at BMI in this case here so now we get these two values and now here instead of console logging the BMI we can call set calculate at BMI and pass the BMI to this function now as a little side note to improve type support types of support we can also configure use state a bit differently we're not getting an error here but we can tell typescript in this line already so before we ever set any stay to it that the state we're eventually going to store in there will be a number we again do this by using this generic type feature with the angle brackets and then we set this to number like this and this tells typescript that the state we're going to manage here the day that we're going to manage in there will eventually be a number it's also allowed that it's undefined initially but when we set a value to it it has to be a number that's what I'm doing here I'm passing in a number if it would pass in a string here now I would get an error that the argument of type hello is not assignable to type number in the end so that's a little bit of extra types of support here which helps us write cleaner code and be more explicit about the types of data we're working with now with that we of course also only want to render this entire row here if we got a calculated body mass index and we want to output the body mass index in here so for dad we use single curly braces and refer to the calculated BMI but as I set a whole row should only be rendered if we have a BMI and you know how that works in react if you want to render something conditionally you wrap it in curly braces and then you add a conditional expression here so here for example we check if calculate it BMI this year if this is set and if it is set so if it's not undefined if it's not false II will output this row here this is how you can do this in react you could also write the ternary expression here of course and say it like this render nothing if it's not set but you can always shorten this to this syntax and use this vanilla JavaScript way of expressing a concatenated conditional expression where the second result will be returned by this overall expression if the first part of the concatenated expression here is true the-- so if this is true fee this will be rendered to the dom and now with that if we save this and I again enter my height here and my weight and I click calculate you see this card down there if I reset this and I click calculate you still see it because we currently have no mechanism of clearing this or of doing anything else but we have the same behavior now as we had it in this application before but now in a totally react - way where we only define the result and different scenarios different conditions like we do it here and react is responsible for actually writing something to the Dom or removing something from the Dom this is our first simple ionic react app with typescript mixed in which can make things more complex if you're not used to it but you will get used to it quickly now of course we are not done yet though we can't improve this application in many regards and we can also improve it from a code perspective and split this huge component we have here into smaller components because that's what we typically do in react development right so before we improve this application in any way we can split this big app component into smaller components now it's totally up to you how you want to split it to be honest there are many possible ways of doing that I want to create a couple of components to show you how you use this normal react approach of splitting your app into components in ionic react apps as well for example I will outsource these controls here into a separate component so these two buttons and I will also outsource this result into a separate component so in the components folder which you already have here if you don't you can just create it I will add a new file and I will name it BM I control start T as X dot T as X as the extension you should use here to use typescript with J as X and it will add a second file the BMI result is X now in app T as X I can grab this row with the controls with the buttons cut it and go to BMI controls and first of all import react from react you need to do that to use JSX then here I create a constant BMI controls that's my component name it will be of type react FC you assign that type with a colon as you learned and then it's a regular arrow function but an arrow function that needs to return J as X so here I will just put my cut J as X code between these brackets and then I also export this BMI controls function here as a default in that file so that we can import it into a ver files now of course we now need to add all those imports here so we import from at ionic react and there we just add all the components we're using here so we import I and Rho we import I and call and I and button and also I and icon we also need to import these icons we got here so we import them from ionic ins / icons from data we import calculator outline and refresh outline like this and now we just need to make sure that we also wire up our buttons to the functions in the app component now we of course do that in the way we always do it and react first of all in the app component we can get rid of these two components which you want which we don't need anymore get rid of the icon imports and instead add a new import here where we import BMI controls from dot slash components BMI controls and you emit the file extension here now that's our own custom component so in our JSX code we just add BMI controls like this now here we now need to pass pointers at these two functions we got here down into the BMI controls component that's how we do that and react how we basically connect buttons or whatever we have in a child component to functions in the parent component so since it's our component we can define how we name those props we could have on calculate prop calculate prop where we point at calculate BMI and on reset prop where we point at reset inputs now the problem is of course these two props don't exist on this component in regular JavaScript you wouldn't get an error here because you're just setting some props which don't exist that's not a tactical error but typescript forces you to write cleaner code it also wants to a white that you make typos for example so maybe we just miss type the prop and in that case we would quickly see that because we have two red squiggly lines here in this case we didn't miss type we just don't have such props in the child component so we should go to BMI controls and let typescript know which kind of props you want to support there for that we accept props here of course and then here on a click on this button we want to execute the function we receive an on calculate right that's the prop name we chose here on calculate we want to use that here and here on the reset button we want to trigger the function we receive on the on reset prop right here we got on reset it points at the reset inputs function so this function is forwarded to be my controls we want to execute it why are the prop where we receive it when this button is clicked but we still get an error here property on calculate does not exist well that's times good you always have to be explicit you have to tell typescript in a more explicit way which kind of props you want to support in this functional component and you do that by also using the fact that this FC type this react FC type here also is a generic type we add angle brackets here and between those brackets we define the props object this will be so the types of data we get on this props object for that we can add curly braces here to define a JavaScript object but now not a new object as a value we can use in this function but as a type definition for a type script dear types would always nose will have a children prop which is this special prop we haven't react to get the content between the opening and closing tags of a component but now we can define that there should be a on calculate prop and this should be a function right and - let's type script know that this should be a function we define a so-called function type which looks like this for example like an arrow function but again this is not a real function or defining but the type definition of a function this says on calculate will be a function which receives no arguments or which wants no arguments and which will not return anything why it means that a function doesn't return anything and will not just have to on calculate function here in our props object but instead you add a semicolon not a comma but a semi colon comma all the works but semicolon is better to make it clear that this is now not a JavaScript object we're creating but a type definition for a type script and there when you define object types you separate your properties with semicolons so then now we add a second property here and that's the on reset prop and this also will be a function that returns nothing if we now hit Auto format it's reformatted to this and now we're telling typescript the dis custom component here will receive props which looks like this so an object where we always have a children prop that is wired up behind the scenes but where in addition to that built-in children prop will have a non calculate prop which will point at a function which takes no arguments and which doesn't return anything and on reset prop which points at a function that takes no arguments and doesn't return anything therefore now this can be wired up here and an app tsx the error also is gone this is how you do that in typescript and react now for the result I will cut this row here go to BMI result import react from react of course like before to find my BMI result component which is of type react see as you learned and then here we export this of course as a default BMI result and in the functional component we returned that JSX code I just cut and just as before we now also need to import from at ionic react we need to import those ionic components we're using here I and row I and call iron cards and iron card content of course now here the value I'm outputting that of course should be received wire props and there it's up to you how we named us here we could have two result or the value prop whatever you want I'll go for a result and again we use this generic type to let types of know how our props objects should look like here we want to have a result key in there and the value now of course is not a function but just a number or a string you could say this will work with both and here this is how you define multiple types and type script you're saying the value here will be of type number or with a single pipe symbol of type string both is allowed because both will work here so now with that we got the BMI result back in the app component we output BMI result now make sure you add import for me it was automatically added here I'll added here at the top I like this better so make sure you import your BMI result component and then here at the bottom we got to BMI result and now we set that result prop and we point this at calculated BMI that's what we forward now with that we can again clean up the kind of ionic components we're import and here in the app component we're not using card and card content anymore and with that out of the way if we save everything this should still work as before but now in a more reactive way where we distributed this across multiple components and you also saw how you integrate this into the types of the world by defining the type of data of your props object now that's that now let's work on improving this application a little bit by also checking the user input a bit better making sure that invalid data is not used and by also making sure that we show an error message to the user if something invalid is entered so let's improve this application a little bit I'll start by configuring some ionic components for one I'll add something which we had before on the toolbar and that was the color we had that before I will re add it here we can simply set the color prop here to primary again just to make sure that we have this blue toolbar looks a bit nicer I think now in addition I want to also change the input types here on iron input I will set the type here to number two kind of restrict the user from entering something which is not a number if we do that you will see that if I try to type hello this shouldn't work here I can enter a number like this however and dad will now both work no matter if I write it with a dot or with a comma so that's another improvement now I also want to make sure that the user doesn't enter zero here for example though because dad doesn't really work the way I want so for that we don't just need changed configuration in JSX but also more logic here in our calculate BMI function to be precise I want to check if entered height here we're checking if it's not null that's good but I also want to check if entered height or weight is negative or zero because both doesn't make sense here so I check if entered height is not a thing or in the entered weight is not a thing or if we made it past these two checks I'll check if entered weight is if I convert it to a number smaller or equal than zero and the same for the entered height conversion to a number is important so that we don't check this for a string where this wouldn't make sense but we check this for the converted number so check if that is smaller or equal then 0 we could also check if once we convert it to a number it's not a number with is na n but we shouldn't really have that scenario here since we configured the inputs to be type numbers so the user shouldn't really be able to enter a string here at least unless he uses the dev tools to do something fishy in which case were fine with breaking this app I guess so these are checks and want to add though and with that added we ensure that if I enter zero here nothing happens now that's better than outputting a wrong result but it would be even better to show an alert to the user and therefore let's see how we can display such an overlay such an overlay component to the user now of course we could show an alert by adding alert here this alert function which is built into the browser where we say please enter valid non-negative numbers and we could do that if we save that and I hit calculate here I get this alert but this is not super pretty it's that default browser alert doesn't look that great right so to improve this we can go back to the documentation and there let's stop back into the components and you will notice that there is an alert component the eye on alert and the preview this looks quite promising now how do we use this alert as always you can read for the docs to learn all about the configuration you can add and you can see different examples with different frameworks and libraries and we're of course interested in react what you see is that you just import an alert from ionic react and in the end you then just render the alert conditionally so it's a very reactive way of displaying this you just render the component when you want to display it you don't render it if you don't want to display it so back in our code that means that here in the app component we're just importing I an alert here like this and now in our app component JSX code we display this alert if we're not happy with the entered values now we can add it anywhere in this JSX code because it won't be rendered in the normal JSX Dom element hierarchy anyways behind the scenes it will always be injected somewhere else so we can also add it here at the very top I an alert however you know in react multiple root level elements are not allowed like this so I will wrap this with react fragment which is this component built into react that allows us to have multiple site-by-site root level elements without really having them as root level elements because we actually have this as a root level element but this doesn't render anything to the it's just there to fulfill this technical requirement react has which is that you must only return one root-level element in your JSX code so now with that we have the eye and alert here and we're getting an error for example that the property is open is missing you need to set this to tell the alert whether it should be visible or not so here we can set is open and we want to show this if we have an error so in the end in order to determine whether we have an error or not we can use state management and set an error state here if we make it into this if statement so let's go here to the top maybe and call use state again to have a second piece of state we managed in here you can have multiple ones as you know extract values from there and that is our error and a set error function now initially we have no error initially that's undefined but eventually that will be a string let's say so we use this generic type feature to let typescript know which kind of data will eventually store in there either undefined that's always an option or a string so now here if we make it into the safe check before returning which I still want because I don't want to continue with the function execution I will call set error and set my error message here which is please enter a valid input value or input number a valid non negative input number so now we're setting this error state and with that here we check if error is truth if it's not null we want to show the alert however for that we need to convert error which is a string to a boolean because is open once a boolean value and we can do that in JavaScript and all's in typescript by adding double exclamation marks here this converts this false e or truth T value to a real true or false boolean so if this is a non empty string this year will yield true if it is an empty string or undefined it will yield false so is open will be true if this is anything but an empty string or undefined so now we'll show this alert in such scenarios we can actually convert an alert to a self-closing component here by the way because all the configuration will happen by our props because now we can also set the message that should be shown and that of course is the error ARR is a string message once a string so that's fine we can also add buttons dad should be shown on that alert now buttons takes an array where in the simplest form you just have an array of strings which is the text of the buttons you can also have an array of objects where every object then defines the text of the button the role which controls which color it has and the handler function that's what I'll do here I'll add a text here of let's say ok and then my handler function now if you wouldn't use this approach here instead if you had an array of just strings you could listen to on did dismiss to do something whenever the button was clicked here we'll do that in the handler instead and in that handler I want to reset my error because we displayed the error to the user if the user now clicks ok I want to reset the error and give the user a new chance of well entering something valid so I'll add a function here clear error sounds like a fitting name and in there I'll just call set error and set this back to null to reset it or actually an empty string and then here the handler will actually point at clear error not executed here but just pointed it so that it is executed for us when that button is pressed again you can learn more about I and alert and different ways of configuring it here in this original documentation now with that if we Safety's and go back to our application and I click calculate I get this alert and this alert here has the Android look if I would switch to the iPhone preview here and reload this you would have to iOS look here but I'll switch back to the pixel here like that so we have once I reload does Android look here and we get this alert we can clear this and we can thereafter of course enter something valid in which case you get no error but if I enter something invalid we do get that error so dad now looks way better and it shows us how we can use ionic and ionic components and combine that with react and that extra flavor of typescript which we also have in there so now let's just finish this up by presenting the body mass index a little bit nicer down there before we then also add more features and for example allowed a user to switch between the metric and the non metric system so that we allow for different values than just meters and kilogram so first of all let's work here on our output on the result I will revert this and just accept the number here so that I can safely call to fixed here and round this number to two decimal places here so by just doing that this will look a bit nicer because now we can enter something here and we just displayed a BMI like this now in addition I want to Center this so here I will add a class name of I and text center because you learned that's one of those utility classes that allows us to well Center the text in addition I'll add an average to tack and therefore actually convert this year to H freitag where I say your body mass index and also Center this and they offer to Center both I'll just add this class on the surrounding iron card content and if we do so and we go back it reloaded automatically this looks nicer I think now you can of course use regular CSS or inline styles to style is even more but I'll have a separate styling section so for the moment I'll live with this default style here instead now let's add more components and let's make sure that we can switch between the different input values and allow not just meters and kilograms but also size and feet and weight and pounds it would be nice to have some extra control here at the top where the user can choose whether he or she wants to use kilograms and meters or pounds and feet if we go back to the official Docs we can scroll through that and you will find a segment button here are iron segment button if you click on iron segment you can see the preview this is how it looks like and this looks pretty neat it allows us to choose between multiple values right and that's exactly what we need we need two values here q well let the user choose between our different systems and of course this exists for both Android and iOS now we can see how we use it we import iron segment and iron segment button and then we just set it up like this here so let's go to the app component and I want to add it here in a new row above the inputs I'll actually add in a new component I'll name the component input controls or input control you can choose any name you want and their import react from react of course have the input control component here which is of type reactive C which stands for a functional component and export it as a default the input control here now let's return some JSX and the JSX we return here of course is this iron segment here this iron segment component auto import isn't working for me here so just import iron segment manually from add ionic react like this and between that now it's working I got iron segment buttons two buttons to be precise because I got two values now in every button we can see it's a good idea to have such a iron label to wrap the text to make sure that the text is presented in the best possible way so let's import iron label and then here we have let's say meters kilogram and on the second button we got the iron label with and pounds now these are our buttons now in the app component we want to add this here inside of a row we could include the row here in the input control we can leave it here I will leave it here so I'll add I and row here and I and call and in there half the input control component we just created and of course we need to make sure that we import this newly created component here so import input control from dot slash components input control like this now back in our application we see the input control here and of course we also can get the iOS look if we switch to that now this is a nice certainly doesn't look too shabby but if you reload you'll notice that no control is pre selected we can change this by going back to the input control and now there are two important steps first of all we need to give every segment button a value basically a value of your choice which you'll later be able to extract to find out which button was selected I'll name this here M kg 4 metre kilogram and here ft/lbs of course again these values here are totally up to you that alone doesn't help us on the overall iron segment we now also have to set value and we have to set it Q the value which should be selected as a default so for example M kg so one of the two values you have down there and I'm using the first value here if I do that and I reload now you see that's pre selected we can still switch but this is pre selected now maybe it would be nicer if the default value could be set from outside though so that we don't hard-code this into this component but we can set it from the place where we use that component and that can be realized with the help of props of course here we could set this to something dynamic and set us to the selected value for example now here again we have to tell typescript which kind of props we get here and we'll get a selected value prop and that will be a string but actually it will be only one of these two strings which we allow so this is either M kg or ft lbs that's all the valid typescript we're saying this is not just any string it's one of these two very specific strings it's either this string or this string only these two values are allowed that's what we're saying here with that we can now use this from outside and we have to set this value from outside now we can set the selected value here q one of these two values and you see I get Auto completion here because of my explicit prop type definition and now again get the same behavior as before but now it's configurable from outside now that's nice we added this control as a next step make sure it's not just added but let's make sure we also can get the currently selected value and use that in our calculation so we're interested in the kind of value the user selected here in this segment button so that we can correctly use it here in our calculation now for that since this is something which can change dynamically we need to manage you guessed it state so in the app component which is where we do a recalculation we add a new piece of state and this is actually now our selected metric our selected calculation system you could say so I will name this calc units and set calc units and the type of data we'll store in that state is either a string of M kg or ft/lbs now initially I'll set this to M kg and of course you could also use our other system here feet and pounds and I will use that state snapshot here to initialize my selected values so this is no longer hard-coded here instead I use my state now D calc units here now I also want to change the state however whenever the user selects a new value so for that back in the input control component we can listen to an event on the I on segment an event which will be triggered whenever the user does choose a new value with on I and change we can listen to this change event how did I know that this exists well the official Doc's are your friend there you see this and you can also read about this here if you scroll down to events you see there is a I and change event which is emitted when the value property has changed and you listen to this with on I and change as you see in those examples here so we know there is this event and I want to trigger a function which I received via props if this event occurs so here I'll add a new key value pair to my props object and I'll name this prop on select valued but the name is up to you and the type here is a function which returns nothing but which actually will take a value and that will be the selected value we got here so here I will have value which should be again this type of data here M kg or ft/lbs now we can't bind this year to on select value like this however because the problem is that on a and change does not omit this kind of value and that's what we would need for this to work if we're saying this function should be triggered when this event occurs it would mean that this event needs to emit this kind of data otherwise types of complaints and it does complain here it does complain because anion change actually emits an event object which will have a detailed property which will have the value the user chose so one of the values we configure down there stored inside of it so we actually need to extract that value from that event object on I and change gives us so we can do this by adding an extra function in here in the input control component input change handler could be a function name we have here there we get this event object which is of type custom event this is a type which is provided by type script by default not just in ionic apps but it by default in typescript and then we can call props on select value and execute us here inside of this function here and forward event dot detail dot value and this is of type any and we know in our case it will be either this string or this string because these are values configured on our segment buttons inside of that segment and now we connect on iron change here to the input change Handler like this an inside of the input change handler we now execute the function we receive on this prop and we forward our detail value which is one of these two values here so either M kg or ft/lbs so now this will be emitted on this on select value prop and now in app TSX we just have to connect this so we add the on select value prop and now here we have to point add a function which expects to get one argument value argument which is either this type or this type of value so now back in the app component we can define a new function for that select calc unit Handler could be a name we choose here handler here is optional I'm using handler here to make it clear that this is triggered upon an event though to be consistent I should then also do this here on the BMI and the reset inputs function which I didn't for historical reasons how we derived this app but I will do it here and there we get this selected value you can name it however you want here this parameter and this will either be M kg or ft/lbs one of these two values because these are the two values we support in our input control component and in here we can then call set calc units which is this state updating function we got here to set our state to this new selected value so here we set the state to the selected value now we just have to connect select calculate Handler to our on select value here like this and now this should be working and we're now picking up the units the user chooses and we store it in our state we're not using that state for anything right now but at least we're storing it now as a next step let's also use that selected state in our calculation then to use the selected units this new state we're managing let's first of all update our labels here to reflect the kind of units we're now expecting so height should be in meters or pounds and we can output this behind your height maybe and what we output here should be dynamic I use my calc units state and that's either M kg or ft lbs right so we can check whether this is M K G in which case the value I want to output here as text in this label is meters since this is the input for the height otherwise I'll output feet here and I'll do something similar here for the weight I want to output some additional information here based on the calculates and I'll check if that is M kg if it is here output kilograms otherwise output lbs for pounds so now we can already see the result here if I switch this you see our labels change which is good gives the user more information about the data that should be entered here now of course we also have to reflect it in our calculation this formula here always works for meters and kilograms now if the user enters value in feet and pounds we have to convert it for this down here I'll add a new weight constant and use my entered weight convert it to a number here however I want to do more than just convert it like this I also want to convert it to kilograms because this formula only works with weight and kilograms now maybe it already is in kilograms then we don't need to do anything but maybe it's in pounds and then we need to convert it so I'll have my weight conversion factor here and that is either one if the weight was entered in kilograms or it's something else if it was entered in pounds now if it was entered in pounds this should be around 2.2 so I'll check my calculator state to see what the user selected and check if that is equal to ft/lbs if it is I know that the weight was entered in pounds so then my conversion factor let's say is 2.2 otherwise it was entered in kilograms I need to do no conversion so it's 1 and now down there when I calculate the weight with which I want to work I divide this by my weight conversion factor and then here I use this converted weight and I don't need to convert it to a number here anymore because we already did this here now the same for the height I got my height conversion factor here and for that I checked my calc units and check if that's equal to FD lbs and if it is in order to convert feet to meters my conversion factor here is free dot - 8 roughly otherwise again it's 1 because it already was entered in meters 10 and then here I got my height which is the entered height converted to a number divided by the height conversion factor and then here we use the height now we should always calculate a BMI correctly independent of the matters the user enter used for entering this so if I save this and I entered this in meters and kilograms I get the same result as before now if we switch to feet and pounds I need to adjust this now i'm 5.8 4 feet tall and my weight in pounds is 150 8.7 so now if I calculate this I roughly get the same result small rounding error because I rounded here too but that tells us that our calculation works if I switches to kilograms I get something unrealistic of course because now that is interpreted as meters and kilograms but in the pound and feet system this works so now we get this included as well and we're again you two a mixture of ionic with the segment buttons on and react with typescript to get there and this really is a great example of of course a very simple application but nonetheless an application where we utilize a lot of react ionic features to build something pretty neat which we could upload like this to the App Store's well speaking off that we could almost do that but it's still just a web app remember so as a next step in the next module we will learn how we can now actually turn this web app into a cross-platform app which does not just run the web but also as a native mobile app which we can distribute through the app stores [Music]
Info
Channel: Academind
Views: 116,524
Rating: 4.9619045 out of 5
Keywords: ionic react, ionic react tutorial, ionic react basics, ionic react crash course, ionic react app, ionic maximilian schwarzmüller, maximilian schwarzmüller react, ionic academind, react academind
Id: _03VKmdrxV8
Channel Id: undefined
Length: 187min 14sec (11234 seconds)
Published: Wed Mar 25 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.