#2 - Quiz App with React and AspNet Core API

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi all this is the second part of building a quiz application with react.js asp.net core web api and material ui if you haven't watched the first part please suppose that first i have given the link in video description and inside the i card top right corner so let's start where we stop in previous video now there is one thing that you must know about context api the values inside the context api will be lost once you reload the application like this here see the participant id is reset to its initial value so how can we preserve the context api value across the application now let's look why it is not working after the page reload and how we can fix the problem first of all we have saved the data inside this component react component state object context so data saved in any react component state object will be lost after the corresponding page reload and this context provider or context api only share the data that is provided here to its children components here so both of these state object and context api does nothing to preserve data across page reloads in order to fix this problem there is a storage facility in web browsers called local storage we can actually see the data saved in local storage through web browser dev tools i will show you that in a bit before that let's briefly discuss how we can make use of this local storage first of all in order to save a data we can make use of this method set item as a first argument we have to pass a key to uniquely identify the data that we have saved and as a second parameter we have to pass a json string corresponding to the data in order to retrieve the data we can make use of the method get item so it will return the data saved inside the key provided here finally in order to remove a data store in local storage we can call this method remove item so that's all you need to know to work with local storage so let's integrate local storage into this application so first for anything that we want to save inside this contact state object we save that first inside this local storage here so you could do this local storage dot set item i will use this key context now here we have to pass the data in json string format so that we can make use of this method json stringify now let's pass this default data here we only need to initialize the local storage with this default object for the first time so first of all we will check whether we have an existing local storage for the context now with this method get item we can check what is the inside this key context we will only initialize the local storage if this context is not already occupied so we can check that by comparing it with null so basically this function is used to initialize the context object here so we have to return the actual data here so we will provide that from this local storage here and don't forget this the data store inside the local storage is in json string format so we have to convert that into an object with this method json pass so this method will detain existing data from local storage for initializing the state object after each time we reload the application now we have to do one more thing from various parts of the application we can modify this context with this function set context right so whenever that happens we have to make the same changes inside this context here also for that we can make use of this hook use effect as a first parameter we can have this callback function and this function will be invoked whenever there is a change inside the second parameter here so as a second parameter inside this array we will pass this state object context so whenever there is a change inside this context this callback function will be invoked during that time we will update the local storage the updated value will be the inside this context so we'll save the corresponding json string in local storage so throughout the application context api data is saved inside the local storage in real time as per context api configuration here the data or the default context must be saved inside the local storage in order to see the data saved in local storage you can go to this tab application so here we have the key and here we have the json string and you could see the corresponding json object here now participant id is 0. now let's try to login with the existing participant that's it participant id is updated to 1 and here we are inside the quiz route now enough with the context api or router or login form now let's go ahead with this quiz component which is the meat of this application so first of all inside this quiz component we have to fetch the questions that we have inside our db now using this question controller here we'll be picking random five questions using this get web method here api forwards last question so first of all we need a customized query here so first of all i'll be creating this variable random five questions and we have to do this through async operations so i will use the prefix avoid underscore context can be used to query the database and here we have the collection of questions now we will make this selection here apart from selecting columns as it is we want some customization here also so question id is equal to the actual question id itself then question inwards image name now here is the difference we have four options and i want to return them as an array called options now in order to return them as an array of strings we could do this we'll be creating a separate array with those options so that's it we don't need to return the answer of this question that will be done later now here comes the random selection you can call this method order by and we are going to order this in a random order that we can make use of this class guide we can call this method new guide so the questions inside the table will be ordered in a random order and from that we will take post five questions now finally we have to convert this to a list now let's return the same here random five questions this project is already running without debug mode here now in order to reflect these new changes we just need to build this project whether go to build then build solution or you can use the shortcut ctrl shift b so project is successfully built now in order to check the proper working of this web api method you can use this swagger interface here so here we have the component question and we want to make a request to this web api method so click on try it out now click on execute boom that's it here we have the server response with the code 200 meaning response when successfully and here we can see the random five questions and the options is returned as we expected in an array now we have to make this same request from this component here and we want to do that after completely loading this component but that we can make use of this default hook use effect here we have the callback and as a second parameter we have to pass an empty array so the callback here will be executed once this component is fully loaded and here we have to make the get request now we can make use of this api function create api endpoint as a parameter to this function we have to pass the endpoint so i will save the corresponding here question so this will be concatenated with the base url and this api here now let's pass the same here and points dot question now here we have to make the get request so that we can make use of this function patch here we have the success and error callback now in order to store the random questions returned from the server i'm going to create a state object questions let's initialize that with an empty array now once we receive the random questions from the server we can update that here response dot data let's print the same into developer console we load the application again now let's check the console tab that's it here we have the five random questions now let's look how to show these questions one at a time inside this quiz component here so first of all we'll make sure the questions are is populated with the server response we'll be showing the questions if the length of the array is not equal to zero else we'll be returning null here now for displaying the question i'll be using the material ui component card inside that we have to show the card content here we have the typography component for showing the question in words variant is equal to h6 so it is similar to nh6 header now here we have to show this property question inwards before that we need another variable to represent the current question that we are dealing with inside this response we have five questions in order to identify which question we are currently showing inside the component we need an index to keep track of the current question for that i will be creating a state object question index let's initialize that with zero now we could do this questions and let's pass the index here now here we have to show the property question in words back to the application reload this page that's it here we have the question now we can list options of this question for that i'm gonna use material ui component list to learn more about this component you can go through the documentation here so here we have the outer component list now for each option we have we'll be showing this component list item but we have four options i will render them with the map function here so here we have the corresponding question inside that we have an array options now we can call the map function this callback has two parameters first for the item itself and then the index inside the callback we will return this list item button first of all i want to disable the ripple effect so we'll set this property disable ripple since we are rendering this component in a loop we have to set this key property with a unique value i will be passing the index here now here we have to show the option i will show that inside a div html div and the option is the inside the parameter item now let's check that here boom that's it so here we have four options now along with these options i want to show the alphabets a b c and d so i will do that with the unicode first of all i will call this method string method from careco now here we have to pass the unicode of capital letter a which is 65 so this function will convert unicode 65 into capital letter a now for second option we need b as a prefix then see so the unicode letter must increment on each iteration here for that i will add the index so it will work as we expect now let's concat a column here now i want to make this prefix in bold so i will be using this b tag here now let's start this card component first of all i will set the width to some fixed value now in order to center them horizontally i will set the horizontal margin mx as auto now we need some top margins so we can do this margin top of the range five now let's show some heading for this card here that we can make use of this component card header okay we have the property title and this will be shown inside the header here i want to show question x of five so here we go question let's concat the question number here let's save this back to the application so here we have the card header each time we reload this page here we will get different questions because we are randomly selecting the five questions now along with this title here i want to show a timer but that first of all we're creating a state object time taken let's initialize that with zero now in order to start the timer we'll be creating a separate function start timer now we can call this javascript function set interval so as a first parameter we'll be having this callback function and then as a second parameter here we have to pass the uh time in milliseconds thousand millisecond here similar to one second so after each one second this callback function will be invoked and this is where we are incrementing this time taken property it is actually representing the seconds elapsed so we could do this set time taken we just need to increment the time taken like this but there is a problem with this approach here this set function for state object is an asynchronous function and it is getting invoked after each seconds if we try to increment this property on each seconds the previous increment operation might not be completed before the next increment so instead of this it would be better to use the callback function inside the set function like this so here we have the parameter previous value and we'll increment the previous value with 1. so this callback parameter previous represent the previous value and i think this will wait for the previous set operation to complete so after each second this time taken property is getting incremented second by second now let's start this timer as soon as we got the question from the server so i will do that here now we need to do one more thing whenever we create or configure a set interval operation here we need to suspend this operation when we done with the counter for that i will be creating a variable called timer the set interval function returns a reference to the created timer and that can be assigned here now as i mentioned before this use effect with this array empty array as a second parameter is represent component did mount event meaning this callback function is getting invoked once the component is completely loaded now if we return a function here like this this function will get invoked whenever we leave this component for example navigating to next component result or reloading the application etc so this is the perfect place to suspend the diamond that we have created for that we can call this function clear interval inside that we just need to pass the timer reference so inside this property we have the seconds taken by the participant now we want to show that inside this card header i will show that with this property action within this typography component instead of showing the time taken in seconds we have to format them in proper time format for that i'm gonna create a separate folder called helper inside that let's create this index.js and here i will paste the function for converting into proper time format so this represent the minutes and this represent the seconds in between them we have a colon now let's call this function inside the component here now let's check how it works so it is working as we expected now i want to align this time up with this title here for that we have to add some custom css so let's inspect this element here we can make use of this class mui card header action so let's copy it back to the component here we already have some custom css so let's add the corresponding styles here and represent this outer card component so that we have this class representing the typography here now in order to center that element we can do this first therefore we'll set the margin as zero now let's set this align self as sender so that's done here we have another problem i think we have misspelled this property basically it was just trying to disable this effect here this ripple effect you know what just don't bother let's remove the property here now in order to separate this card header from this card content here i'm gonna use this material ui component progress we'll be showing a progress bar like this indicating how much questions attended by the participant that in between this card header and this card content first therefore we need a box which is similar to the div in a plain html now let me copy this component from here now here we have to provide the value in percentage so i will do this first of all we need the question number so question index plus 1 divided by 5 resulting value indicate how much fractions of the total question is completed in order to convert this into percentage we will multiply this numerator with 100 boom that's it now when users select an option from here we want to show the next question right and we want to save the selected option along with the corresponding question id and that's all we need for the final score calculation so first of all let's add a click event to the list item here so here we have the on click event to this event function we have to pass few parameters so i will call the function inside another arrow function here update answer first of all we have to pass the question id so let me copy this and pasting here question id and then the index of the option it's the inside this parameter idx now let's define this function up above we have two parameters question id and option index first of all let's update the selected option with the corresponding question id we can save that inside this array context apira selected options first of all let's destructure what we have inside the context the context object and corresponding set function set context now we can call the hook use state context so inside this context object we have the array selected options into that we can just push an object with the question id and the selected option index so question id is equal to question id parameter we can simplify the syntax like this and then we have the selected index so i will pass the option index here now there is a problem for doing this because this state object is immutable we can't directly update the state object context here it's immutable so instead of doing this first therefore i will copy the array here let's destructure the array and this is how we copy an existing array now let's call this push method from this copied array now finally we can update these context with this function set context into this function we just need to pass an object with updated property value so selected options array must be updated with these new values now along with this we have to increment this question id here with that we could do this set question index let's increment it to the next index now inside the context api we have to update the time taken for this quiz program and we will update this property time taken after completing five questions so i'm gonna have this if block here if question index is less than four we will do these operations else here we have the last question so we don't have to increment the index along with these options we have to update the um time taken for this quiz program so time taken is equal to we will pass this state property here time taken we can even simplify that like this so this else block will be executed for the last question so after the fifth question we have to navigate result component sorry i misspelled this if keyword here before getting into the result component we have to do few more things inside this quiz component here now let's check whether it is working as expected let's see the logger storage side by side now select an answer for this question boom so the question is changed and also the selected option index and the corresponding question id is inserted to the local storage so it's working properly fine now let's complete five questions five options selected by the participant and the time taken for the quiz program is updated inside the local storage of the contacts api so navigation through those questions is working perfectly fine here we have forgot to something for this question we have an image of a mouse we want to show that just about this question and below this card header here so let's do that before moving forward we want to show the image in between the header and the content and we will show the image only when there is an image named property for the question so we can do this image name is not equal to null then we will show the image here else null for showing the image we can make use of this component card media the corresponding html component will be img now with this property image we have to pass the image url so inside this api file here we have the base url right and we have exported the same here now we can make use of that here base url and inside the api we have a folder called our images inside that we have this image with the name given here now let me save this and back to the application let's reload this page again and again until we find the question sorry image is already showing for questions without image so here so here we have to change the condition to not equal to null let's reload it until we find the question for the mouse so here it is you see it's not working as we expected actually the image is there inside the folder images with the same name that we have saved inside the db in order to solve this problem first of all we have to enable static files for this api here for that we can go to this program.css here now just below this course configuration from the app object call this function use static paths now into this method we have to provide the directory where we have saved the static parts so we could do this static file options file provider is equal to new physical file provider and let's add the corresponding namespace now inside this we have to pass the directory where we have saved the images so path dot combine method can be called now we can make use of this object builder environment dot content root path will give the path up to this uh project directory here into that we just need to append this images which is the name of this folder here now as a second parameter we have to pass this request path so this is the route that we want to use for accessing static files inside the older images here now let's build this project now let's try it again let's try it until we find the question for mouse boom here we go now actually here we have to apply some custom css to place the image properly before that i want to show you the current state of the context api or local storage see here we have lot of questions as a result of reloading this quiz component here so let's fix that first we just need to reset the context api inside this component did mount event here set context let's pass the object with updated values so first of all we have time taken property let's assign it with 0 and then the array selected options so this will do the job now i want to do this similar full reset operation of the contacts api inside this login component here because we can navigate back to the login component like this in these cases also things might mess up so let's do the full reset inside this login component also so first of all let's import user effect we can make use of this snippet use effect snippet we just need an empty array and here we can reset the context api and local storage now this same operation can be reused in other components for example if you want to log out from this application this reset operation might be helpful so i'm gonna define the function inside the returned object inside this hook here along with this set context i'm gonna define a function reset context and this function will be only available if we restructure the property reset context right okay first of all let's remove the context from local storage now let's reset the state object context we just need to call this function get fresh context now inside this login component we can restructure this property here and let's call this same inside this user effect here from both of these components login and quiz will reset local storage or contact api properties to keep the integrity of data saved from the application now back to the mouse image here so here we have the custom css to properly align the image first of all we'll set the width to auto now in order to align the image horizontally in center i will set top and bottom margin 10 pixel horizontally i will set the margin as auto so it is working perfectly fine now before moving to the result component we want to show a top now bar here inside that now but we'll be having a logout button to quit from this quiz application and this now bar must be available inside this result component also how can we do that for that i will create a new component layout.js for the top now boy you can make use of this material ui component app bar so first of all i will add the component here app bar i will set the position as sticky now inside this we need this component toolbar let's import this app by component also for this toolbar let's set the width same as that of the card so width is equal to 640 pixel and let's set the margin as auto so that it will align horizontally in center now let's show a heading with the app name quiz app variant is h4 so here we have the title quiz app now in order to show this app bar for both of these components this should act as a parent control right or a layout for these components here that we can easily accomplish with the router so here we have the router configuration inside the app component now let's wrap these two components quiz and result with the route layout component path is set as a for slash element is equal to layout component so here we have the corresponding close tag now if you navigate into those two components you could see the app bar see but the actual html from the component is not shown to fix this we can do this just add this stack outlet so whatever we have inside the targeted component according to the current out will be shown in place of this outlet here now this component render method does not allow two outer components so let's enclose them with react fragment like this so here we go you know what when we use react material ui components it's better to enclose everything with this container component so let's do that here now inside this app bar let me show a lockout button here we have the click event logout let's define the same function here during logout operation we just need to clear everything from the context api and we want to navigate into the login form right so first of all i will use the hook for the state context we just need to import this uh reset context method use state context now for navigating back to the login form let's create this navigate object first of all let's reset the context now we get back to the login form so here we have the button before trying this out let's align it properly that we just need this custom css plex grow is equal to one so this heading will take all of the free space and thereby this logout button will push to the right side now let's check whether it is working or not that's it now let's check the local storage so the reset operation is working as we expected now let's login into the application again now before moving to the result page i want to make one more change here inside this application here by default in react material ui the default phone is roboto instead of that i really like this font from this material ui documentation here if you inspect that you could see it's called ibm flex sense so let's grab the same from google fonts so here it is now i will select these phone weights 400 500 and 700 now let's copy this link from here and let's replace the same inside the index.html here so let's replace the link like this now let's change the same inside this global css here index.css i will set this phone as the first option back to the application let's check it is working or not no it's not working if you inspect here still it is using the font row bottom so this is by default inside the react material ui in order to override this rule we just need to customize the theme like we have done inside the index.js here so here we go typography and let's reset the default family with this font save this back to the application reload this that's it you can skip this step if you are fine with the default font okay now after these five questions let's navigate into the result component here we have the else part and this is where we have to navigate into the result component first of all let's create the navigate object so here we go navigate over slash result let's check that here boom that's it so this is the final component inside the application hope you are happy with the progress that we have made inside this component we have to show the score of this quiz program along with the correct answers in order to calculate the score first of all we have to face the answer for the attended questions and we want to compare that with the selected options after all we have to show each of the questions with their correct answers that will be discussed in next video for more react osp.net code tutorials like this please consider subscribing to this channel coder fiction please like and share this video with your friends and colleagues see you in next video
Info
Channel: CodAffection
Views: 6,342
Rating: undefined out of 5
Keywords: CodAffection, react quiz app, react projects, .net core web api, react game, react project for beginners, react and asp.net core api, react quiz app with timer, asp.net core web api quiz, material ui quiz app, real world project with react material ui, quiz app, build sample project with react.js and asp.net core, latest material ui, material ui v5
Id: uii_TmfCjiM
Channel Id: undefined
Length: 32min 18sec (1938 seconds)
Published: Mon Mar 14 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.