Todo Project using Angular 16 with ASP NET Web API

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys what's up um today I am going to show you how to create a to-do project using asp.net web API angular 16 and bootstrap all right so this is our empty folder I'm going to create two folders here one of them is gonna be let's say to do app dot API this is our web APA project and another folder is for uh UI which is going to be angular UI okay so I want to create the web API project in this location I'm using visual studio 2000 2022 but you can use um other version as well create a new project I am going to use asp.net core web API also I'm selecting that next I am providing here the location of the folder and the project name is to do app dot API okay hit next so I have here dotnet 6.0 or 7.0 you can use either of them I'm gonna use dotnet 7.0 create okay so we got here default weather forecast controller which I would like to delete it also the model okay let's build it okay um at first I would like to add the nuget packages so right click on the project and hit manage new get packages here in the browse type Entity framework core and make sure package source is nougat.org okay I'm gonna use Entity framework SQL Server also tools for tooling this entity primer core the tools it will help us to add migration update database all those command okay so far so good and I would like to add couple of folders here one is going to be data folder to create the data context and other one is models folder okay and we already have controllers folder at first I want to create the model right click on the model add a class I'm going to give the model name as to do okay and property is gonna be oops prop um let's say guid ID property um string title Maybe for to do title or maybe description okay and another property for date time like um created it okay then another one is for I'm gonna use a bull for is completed okay what else maybe I can use completed date which is gonna be date time and it's gonna be nullable okay and the property name is completed date okay so we have the to-do model then I wanna create the DB context which is gonna be under data folder right click on the data add a new class I'm gonna give the class name as to do DB context and I'm gonna inherit it from DB context okay so it is from Entity framework core let's add the Constructor which is DB 2 root DB context and I'm gonna pass the parameter DB context options and pass the options to the base Constructor and also adding DB set for our 2do Plus okay oops it's gonna be to do and control dot so we can import it from the models right and we can give it a name to lose okay now let's add the connection string in the app settings dot Json file connection string and we want to give the connection string name to DB connection string okay so here we have to provide the server right in our case I'm gonna use the server localhost then database name let's say to do trusted connection equal true trusted or trust server certificate equal true that's it okay now let's go to program.cs file here I would like to add that DB context in the service so build their services at DB context and type is to do DB context okay and in the parameter options use SQL server okay the SQL Server we want to pass the connection string from configuration get connection string and provide the connection string name in the method which is going to be this one okay and let's build it so far so good okay now let's create the um controller right click on the controller add new controller I'm gonna I'm going to use API controller give the control name to do so this is our controller and I need a private read-only variable for to do DB context and give the name underscore to do DB context okay and in the Constructor I want to inject that to do DB context and assign it to our local variables okay so at first I would like to create the get method that will return our like list of to-do's okay so public async task I action result let's say method name get um get all to do's okay so it will return us all the to-do's so but to do is equal um a weight DB context to-do's to list as seen then finally return okay with the to-do's okay so let's run it so this is about to do method get to those right if I try to execute I get 500 internal server error because it is trying to establish an uh a connection with the database so far we did not create the database right that means we need to create our database so we have the data context also the model now we need to execute some command in the package manager console okay First Command is going to be at migration and give it a name Maybe initial migration and you will see there is a migrations folder and it created the table definition here okay and then another command to update database done let's see if you connect here and if we open the databases we can see through database has been created and if we expand the tables there's also a table named to lose at this moment it is empty okay which makes sense because we did not insert any rows so far okay now let's run again I want to make sure API is running smoothly okay now I got 200 which is okay and response word is empty because we do not have any Row in the database okay so what we can do we can add another method which is gonna be HTTP post and that post is gonna be public a sync task action result let's give it a name add to do and as a parameter I want to add to do class here and give the object name at s to do so we don't want to pass the to do grid from the UI side so every time we create to do we want to assign ID in the UI I mean in the back end which is in the FBA site right so to do dot ID equal the new guid and to do the context to do's right we can add after that await say changes async then return to do right now let's run it and try to insert or try to post to do so we got like um ID here with ID description let's say this is our first to do right create a date is fine it's completed it's false and completed date it can be none because we assign the variable as a nullable right hit execute and we see 200 status code and this is the response we got and if we see the database execute and we see that um this is our first to do description is there and complete date is null we can also expand the columns and see the column definition which is date time nullable okay now let's create our UI which is here right to app dot UI I'm going to open the terminal here or if you open the CMD separately and you can navigate to this folder um first of all I can check the NG version I have currently I have NG CLI which is 16 point 0.4 which is the latest one okay and I'm going to create the project which is going to be NG new give the project name which is to do app dot UI would you like to add the angular routing yes and you can use this CSS scss sales list anything but I'm gonna use CSS it may take couple of minutes um I'm gonna pause it little bit and I'll be back as soon as it is done okay now I'm gonna CD to our to-do app dot UI folder oops it's gonna be to do now code space Dot yes I trust the authors because I created the project so this is our project I want to open a terminal let's run the NG build succeeded now and this sir Dash o okay so this is our default template right um so what we can do we can remove the default template from the app component the HTML right so it's a pretty big template we have by default which I would like to remove the entire template and also I would like to keep a router Outlet and if we save it and you can see that this is now empty okay and in the index.html I would like to add the angular not angular bootstrap CDN so from here we can copy this CDN for CSS then paste it in the head section okay then what else um I would like to create a number search never in the neighbor which I want is maybe something like this let's copy this and I want to show it side by side okay paste it here save it and we can see the in the UI and I'm going to give it a name let's say to do app right okay and I want to give it like to Do's or my to-do's right for now I don't want anything else so to do's and if we expand we should see the to-do's here okay first of all I would like to add the app routing this is empty now so app routing is gonna be a combination of path and component right so at this moment we do not have the component and so what we need to do we need to create the component so under app folder let's create few folders one of them is components um models and services okay now let's open another terminal here terminal new terminal okay so navigate to that component location which is Source app components right so here I can use angular CLI command to generate the component NG G4 generate C for component and the component name which is gonna be to lose okay if we expand and we can see this is about to lose component now we have the components so what I would like to add is here like to do's component here okay so whenever path is empty I would like to display the tools component also we have um another Pathways is to lose right for example localhost colon 420 then to do's right so what we can do for this we can create another route which is and component is again two rules component right so now I would like to add the router link here so this router link is gonna be to lose okay so this is the router path here we have assigned we have declared here this is the path right as soon as it hits the this path and we are going to display the to-do list component this is what it is okay so if we go to the browser and if we click on octurus app which is the home you see the turos works and if we click on the to-do's you see that um URL got changed still when the to-do list component I want to um change a little bit in the UI which is gonna be um in here let's say oh never dark background dark okay we got another can also the background background dark and I only use only the container so that we can display the content in the middle if you see this starts from here and ends over here what else I think for now this is good okay now let's move into our to-do's component okay so in the two rows what I want to do is like I want to add like a list which is gonna be a table okay so in the table um how can I get the table let's go to the bootstrap search for table and this is the table template we have um so we can paste it here right before that I want to use like a container deep container right and then I'm going to use another deep per row inside the row I'm gonna use the table so oops we save it and we can see in the UI got changed right um maybe inside the row I can use H one tag let's say add to do or maybe this is gonna be like two rows right list of to-do's or you can give it like my to-doos okay and I want another deep oops in the Deep I'm gonna use um a form control so that I can add the to-do there right so I'm gonna use form so I need a text box and a button so this is gonna be the perfect for my situations right so what I need I do not need all these I only need one button and give it a name let's say description right and this is gonna be prescription here right then email type is text and ID is description and do not need the help at this moment right as soon as I say I see that um this text box has been created right this is great so what I can do here oops it was a road supposed to be Raw and maybe I can use another H1 Tech here let's add to do right so we can add the tutor here what else Okay so in the table we need maybe ID I think we do not need the ID here let's say description then what created date then completed right I think for now that's it uh in a tea body we need one row only this moment because we're gonna Loop through the least right um so so uh before creating the list I'm gonna add a model here add new file to do Dot model dot TS okay and this is gonna be export interface to do here I want to add ID as a string and description string right it's completed it's gonna be a Boolean what else created date this is date I think that's it right is completed and completed date right this is gonna be another date here right so I can put the date that is completed next to the completed date that looks better okay so now I have the to-do component I mean to the model so I can create a to-do's which is a list of to do at this moment that is empty and I need to import the to-do so control Dot import the package okay so now let's go to the component so I need to add ng4 led to do uh to do's do not need this scope here to do the description to do Dot created date then true Dot is completed right so we see there is a description oops something wrong here okay at this moment that is empty so we need a service to um called API and then we can subscribe the service so that we can display the list here okay so what we need to do we need to create the service that's expand this one so I need to go to the service folder which is going to be services then NG generate as for service and give the service name to do so it will create the to-do service expand we can see to do T service dot UMTS okay so at first I need a base API URL this is going to be string and that base APA URL is gonna be so we need to run the API project again so that we can see so this is our API URL base URL okay so we need to go our angular project provide the why it is complaining can't find name String oops typo okay so in the Constructor I need HTTP client right CLI ENT and if we press Ctrl dot we don't see that there is no suggestion so to fix that we need to go to our app.module import http client module from um angular common http then we need to include it in the Imports which is http client module right now go back to our service control dot now we can see the suggestion so we can we can import HTTP client okay so far so good so we need a method which is get all to those right and once we get the response we want to make it observable return so that we can um subscribe from the controller and I will return list up to do right we need to import the to-do model here so return this http when I get what we would like to get to do and list hook to do from this base e API URL right and what is the API method name that we can also find it here so this is the API method API slash to do so slash API slash to do right so that is gonna be our API URL okay so now let's go to our component here and I wanna implement um that is going to be Ng on in it right so that we have to have the implementation here which is NG on it okay so what do we want to do you want to call the service right so to call the service we need to in inject that through our Constructor right so Constructor and um in the Constructor what do we need we need to do service private to do service and also we need um I think at this moment that's it right okay so these to do service get all the to-do's once we get the response we're going to subscribe to our observable return type right then um next that means if that is a like success return I mean if it returns 200 right so that means that is a success then we want to do listings what we would like to do would like to sign that to those into our local Cruise that's it let's save it compile successfully let's go to our UI so far I do not see the list here let's inspect is there an exception error or something right the console we see it shows it has been blocked by course right so to enable the course we need to enable that course in our API project so to enable the um course what I would like to use app dot like use calls in the use course you want to add the policy um allow any origin allow [Music] um maybe any header right allow any method okay let's run it once it is up and running we can go to our API and if we refresh we see that there is a return from the API right so this is our API response see and yeah now I would like to work on the ad to do here right okay so to add to work on the attributors I have the UI ready here right so I need to include like um NG form this is gonna be form and the form right and as soon as we hit the submit button so that will call this method add to right so that add to do is not available in our component so we have to create that add to do say still error because of NG form right so we need to add that forms module in our app dot modules so import s module form from angular forms right and include in the Imports which is forms module save it compile successfully okay let's go back to our component hmm let's create the another local variable which is new to do right type is to do and I'm going to assign the default value so this is going to be let's say ID is empty right we have a description which is also empty and create a date uh which is gonna be new date and it's completed say false by default right and completed date is also a new date okay so now we have the new to to do um we do not need this guy here so what we can do we can assign the NG model which is gonna be our new to do Dot description right say compile successfully okay um so far so good so what we need to do now we can create our service the service is going to be add to do we're gonna pass the new to do as type to do right and we're gonna use observable to get that you do so new to do on a pass ID like um an empty guid right oh this is gonna be this one you can Google it like type empty wheat right something like this empty good so you will get this uh good the Google okay then return this like uh http when um post this right post we'll get the response as to do in this base URL and slash API slash to do this is something you can find it in the Swagger UI you see this is our post API method slash API slash to do right and then pass the new to do save it compile successfully now we can call this from our add to do method so this like to do service add to do we need to pass this new to do subscribe right and as soon as we get the response if it is success we get by responses to do right so once we get that to do what we want to do we want to reload the base right um to experience that let's create a to-do here this is our second to do right hit submit and I do not see that is here right if we refresh I can see that today has been created but I do not see the description here if I check in the database tutor has been created but description is null why is that so I need to inspect the issue let's do one thing let's log in our console this dot new to do I know why it is um creating the issue but I want to inspect it here so that you can learn it so if we inspect the issue we already see it right it says if NG model is used within a form tag either the name attribute must be set or the form right so um what we want to do is we need to use a name attribute here that's the solution right and I want to show it like real time so as soon as I save it that error has been resolved right so now if I create this is our third to do submit and if I go to database you will see this is our third to do but this is not being updated here so what we can do as soon as we get the success we want to reload this uh my to-do's table right so how can we do that let's go to our um to do component.ts file this is the API call that that gets all the to-do's and displayed in our my to-do's list or table right so what I can do we can um create another local method here right and then we can reuse that method so I simply refactor the code as soon as we get the response here a success I want to refresh the table okay save it there let's create the one other one this is our fourth to do hit submit and we see that that it is being added I also want to format this one little bit um so what I can do is like um created date right so in the created date I would like to add a date filter which is like date and I can pass like format month day year right hour minute AM PM oops why is that maybe it's a small d nope unexpected token here which is this guy okay we see that has been formatted right and I want to make this um true false like a check box here right instead of true and false so if I add a checkbox here I can check it like if I click on check that means it that means we can mark it completed right so for that what I can do I can add a link and not the link uh it's gonna be input type checkbox right and then um let's see how it looks like okay checkbox is there now I want to um map with our variable so this is gonna be like checked so it's gonna be checked if to do is completed hmm it's like our all to Do's are completed but that is not the case right it supposed to be false so what is happening like this to do dot is completed right what about if I use the error is still same that means something wrong here um who is I want to investigate little bit um for that oh I I just got it I have to use the the bracket here okay so how can I test it if I mark it through yeah because not false when it's true okay sounds good so if if we click on this um check box right that means change event if there's a change event I want to call a method Let's uh let's give it a name on completed change right and there I want to pass like to do with ID and to do itself right so I need to create that um method the component so here ID is gonna be string and let's give it a name new to do no I mean to do it's gonna be two to type right Okay so what we want to do if we click on this checkbox right we want to call a service to update that you do in the back end and also reload this to row in the UI right so at this moment we do not have the API right so we need to create that API like update to do or like updates completed let's go to the controller this is going to be http post output right and you wanna give a name like a sync task I action result update to do and from route we will get like um do it ID and to do which is gonna be to do update request okay so what do you want we also want to pass the route here ID is a GUI type okay so bar to do have it from to-do's right find a sink buy ID if to do equal equal null right then return um not found or what we want to do is like um we want to update like it's completed equal to do update request that is completed okay and then simply hit the save changes and return the to-do I think that's it okay let's run it first of all I would like to find that to do we have I want to update this one as completed right then go to our method this is our API I mean ID um what was that we simply want to update 7 app this guy right we simply want to update that is completed equal true right what else why it is description is empty oh I choose the wrong one I mean let's choose this one and ID is gonna be this one so change it over there I want to mark this as true right and we also need to update the completed date right that means we have to update in the in here through the completed date equal date time dot now right so this is the time we are completing the to-do yeah okay so we need to reload that let's take this one and and the ID is this one and to complete it true and the completed date is like right now it is um let's say it was created on 6 19. let's say it's like 45. okay hit execute so it was succeeded right and we see the is component is true also the ID that has been updated on the completed date now if we see in the UI hit the refresh and we see this is completed right so this is what I want to do from UI right so for that let's go to our um angulars project and in angular project we can call the through service right so in the to-do service we do not have that API method yet so we need to create that one update to do ID string right to do to do observable to do okay so return like um please http this one that was a post I mean put method so we'll get back as to do from this base API URL and what else plus if we see that after API Slash 2 do slash we have the ID right so that means we have to append that ID here then we have to pass the turo in the body say now go back to our component call the update to do and pass the to do right also need to pass the ID subscribe next um if we get back the response right if we get back the response I would like to refresh the UI which is gonna be this guy perfect let's see if I click on this nope and this doesn't work now um I want to debug it in the UI right so let's add debugger here and also open the inspect tool here right and if I hit on the check box now we got a hit in our and if I see a tool I mean to do is completed still false so that means what we need to do is like we need to reverse that is completed to do is to do the negate the is completed a Boolean variable right so this is what we needed save it and if we hit this guy right so it got refreshed no no still there is an error let's see what is the error here the console so it says invalid maybe invalid API let's check our API method so base API oh we forgot to include that API slash to do slash then plus ID right so this will resolved our issue I hope so let's restart again Ctrl C and this sub Dash o so hit and refresh yeah and if we want to see the yes completed both of them right so that means that is working okay now I want to add delete button here so to add the delete button you need to add th here and also oops 3D I can use ATEC right let's say delete okay so now we have to use like router link which is gonna be empty right so this is our delete and if we click on the delete link we want to delete the to-do right so what we can do you can simply pass the ID so delete to do let's go to our controller create that delete to do look at the ID as a parameter okay so now we need a delete API right okay so to create the delete API I need HTTP delete also we're gonna pass the route uh with um guid right public sync task action result delete to do and from route we will get the grid ID so what to do right away um ID if to do equal null return not found right or to do that delete it so we do not have that property yet right so to create that property first I want to comment out this one and go back to our to-do um model now let's add a couple of property Boolean is completed right and other one is like date time completed date right oh it says it's completed actually it's gonna be not completed delete it and this is gonna be deleted date right okay and now I need to use another command um let's say add migration and give name like edit delete um fields then use the update database done we can take a look in our table let's refresh the columns and we can see that we have now deleted date and is deleted is there right so um we actually need like um delete at date it's gonna be uh what is called um nullable right so let's upgrade again at migration updated deleted date to the level okay update database done see yeah it's null um okay now let's go back to our controller right undo this code and now we can assign this deleted equal true and to do the deleted date it's gonna be now right then we can you know the same changes return to do that's it so this is our delete I want to get uh ID let's I want to make this one as deleted so what we can do get the ID come back here press ID and if you see is deleted is true and deleted date is also the current date time okay now we can also check in our database that this one is deleted right now we need to check in our angular UI so for that let's run again and this sir okay this is deleted right but it is still showing up in the UI so because in our um get all to those we we are taking all the to-do's right so here we need to filter so what we can do like um from to-do's we can use fire x dot is deleted right um like we want to get is deleted X false because you wanna display only the active to those then also we want to use order by descending right text success x dot create date and then to list right so we'll get only to those whose are active so is deleted equal false now let's run also we need to serve again sorry I didn't realize that this was out of our screen okay so now you see we have only these three because the other one we marked that as deleted right so let's delete this one also hit the delete no response because we did not do anything here right did we create the service yes so we we have created the service looks good now we need to add the um to do I mean delete to do so this Dot to do service right it's gonna be delete to do what is that oh it was update to do not the delete to do so update to do and delete to do is pretty much similar so what we can do delete to do string right and it will return observable to do return this http then delete get back to do this base API URL Plus API um to do right plus ID so this is our delete to do right so what we can do can come back here and we can pass the ID and then subscribe so if this is your success response I would like to um call these get all to Do's method meaning these dot get all to those so that we can refresh the UI okay let's delete our third to do hit delete it our third to do and we can check in our database third to do this is also marked deleted okay we can also add another to do this is our feet to do right okay looks great I also want to add like a strikethrough here in the description text so that as soon as we Mark that is completed then we can show like that is a strikethrough right so to use that strike through we can um take help like like we can use CSS there is an option for us so let's go to our angular component right um this is a description so in the description I want to use a class a stroke okay and that is gonna be a tip if to do is smart completed okay and then I need to add the CSS for that so this is the CSS to dot component.css for this HTML come over here a stroke class name so our class name is a stroke and when that is active we want to use text decoration like line throw okay yeah so this is our line uh through here if I click on this one completed that is completed if you refresh still that is there perfect so now what else we have deleted couple of the to-do's right now how can we see all these Studios right so you can have another menu here that um if we click on the menu you can see the list of two rows there right so for that we need to create the um component which is gonna be like so let's give it a name let's go back to our CD component right NZ generate serve let's give it a name deleted to do component now we have a deleted oops my bad I supposed to execute like let's delete this okay NG g c for component deleted to do okay now I have the deleted tutor here right now we also need to add that in our app component so to those maybe this is gonna be my to-do's right and I'm going to create another link let's give it a name um delete it to lose rather link gonna be deleted to do's I think that's pretty much it save it and if we wanted to run again and this serve and if we hit over here so this is our deleted to Do's right so we need to create that um routing come up right here create that path this is gonna be deleted to do's and component name is deleted to this to the component right now if we go back there hit there and see the URL deleted to do this and that is like empty so we are gonna work on that one okay so what we want to do here we want to have a deep container then take my base three like my deleted tools right maybe other lowercase is fine and then um I can get this deep here that is kind of almost pretty much similar right so description created date I need another one for delete it date right then completed is fine and in here create a date another one is like deleted date right and I do not need any more checkbox here right so what we can do you can use plane is completed true or false is fine if you want you can also customize that um so for this to do I'm gonna use like another link um so that we can um undo that uh that you do right so we also need router link controlling is gonna be empty okay we need to have the to-do's so to get that to those uh to those to do which is empty control dot okay then Constructor pass private uh to do service need right um what else I think that's it we need it so in the page thought so we need to implement like on init engine in it so here I want to call to the service like on um maybe get all deleted to those right get all deleted to those so we need to call that one as soon as we get that subscribe that one and the next response we want to do like we can refresh the page or we can assign it back to our to-do's as of now we do not have that method so we can create that service right um get all deleted to do's so that will return observable to do list this return these or http it's gonna be get right um to do list from this base API URL API slash to do slash so at this moment we do not have that um that method in our API site right so what we can do we need to create that API in our API site so we can create another get method here similar to that public sync task action result get deleted right and since we have another get a method we need to specify the route here I want to give the route name as like get deleted to Do's like this so here bar to those 12 away um to do's where it's gonna be opposite of the the previous method is deleted is gonna be true right then we can also order by descending by create date then to list a sync finally return to this okay this is the to-do method we can also see in our API Swagger UI okay get this one get deleted to those if you execute we see we have two deleted to-do's in our database and if we refresh the database we see you have two deleted to do's right this looks great so now what I need I need this route in our angular project okay okay I have now some error property to those does not exist on type this component so if we see our model um we do not have that deleted column here right is deleted Boolean and deleted date is gonna be date okay now we have to fix other properties here is deleted let's say false deleted date new date okay succeeded so if we know and this serve again and if we go to our my deleted to those we see we have the two to Do's here and if we now we are gonna undo these two Do's right so we need to work on this method um so in the UI what we need to do we need to add a click event here if we click on this um undo um link we're gonna say undo delete to do and we can pass to do ID and to do itself right so what we need we have to go back to our component the method ID string to do to do so oops there is a typo issue it's gonna be ID okay so what we want to do here in the undo to do I'm gonna call to the service like undo delete to do right then I'm going to pass ID and to do then once we get back response and if that is like success then we want to refresh the paste which is this is the method it's refreshing right so we can refactor this method and oops I create another local variable local method here get like uh all deleted to lose put it here right then we can call that method from there so that we can reuse that same method here okay so we do not have this service yet we have to create the service you're going to take ID string to do studio type observable return this http um it's it can be put method let's say right so at this moment we do not have that API method ready please I'm gonna create Right Now API are set to do slash say um undo deleted to do slash the ID right and I can pass that to do so I want to copy this and I wanna go to our API project so let's create HTTP pause a put and Route it's gonna be this one slash ID um which is guid a click a sync task action result uh undo deleted to do right from route yes yeah from route ID then to do is like undo delete to do request okay hmm but to do I'm gonna get oops I wait to do find a sink ID to do if to do is now then return not found otherwise to do delete date equal null it is a nullable field and to do is delete it equals false right and then avoid save changes return the okay with the to do that's it so if we reload the API okay undo deleted to do so what I want to get I want to get the ID from here let's say this is the ID right that um third to do I want to bring it back to our active to those ID um in the request story it doesn't matter see now it's completed is I mean is deleted is false now if we see this is gonna be zero now execute zero and if we see in the UI if we refresh the third photo is gone back to our regular my to those list right although it was like completed a marked is uncompleted okay so we can undo oh then we have to invoke that method in our API here so let's go back to our deleted to do okay we did it Maybe it was not running undo what is the error let's see hit undo maybe refresh okay it is save it maybe I did not say let's see hit undo yeah it's gone and delete this one this one this one all this you come back here all of them are here see true and false you can see it was completed right okay hmm yeah this is pretty much it I hope you enjoyed this um project or you can enhance this project like you can use more you can add more future on top of these sample project right if you like this tutorial please subscribe this channel also hit the like button and if possible please share with your peers or friends or colleagues thank you so much
Info
Channel: Ripon Datta
Views: 10,373
Rating: undefined out of 5
Keywords: asp net core web api example, asp net web api example, angular cli, angular project
Id: 4Zo_c_lI0xs
Channel Id: undefined
Length: 96min 28sec (5788 seconds)
Published: Wed Jun 14 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.