BlockVote JavaScript Edition: Build a JS Blockchain Voting App
Nothing is loaded from YouTube until you press play, and then without tracking cookies.
About this video
Promised and delivered! Dorian is bringing back Blockhead's hit NEAR tutorial, the blockchain voting app, but in JavaScript using NEAR's new JavaScript SDK.
0:00 - Intro 0:30 - What are we building/what do you need 3:25 - Setting up create-near-app 12:24 - Writing our smart contract 46:00 - Writing App.js 1:06:00 - Writing Home.js 1:17:30 - Creating New Poll Form 1:51:00 - Creating Polling Station (Final Section)
Need a quick refresher on React? Watch this: • React JS Crash Course
Want to watch the original Rust version? Find it here: • Blockheads Ep 10: How to make a blockchain...
---
Join NEAR's community: Website: near.org Reddit: / nearprotocol Discord: near.chat Medium: / nearprotocol Blog: near.org/blog Twitter: / nearprotocol GitHub: github.com/near github.com/nearprotocol Dev Docs: docs.near.org Create a wallet: wallet.near.org/create Apps on NEAR: awesomenear.com Learn to Build On NEAR: near.university Grants & Funding: near.org/grants #Blockchain #FutureisNEAR #NEAR #nearprotocol #nft #dao
Transcript
20,916 wordsCaptions as YouTube publishes them, usually machine-generated, so product and people names can be misheard.
- 0:00
hey everyone so I'm really excited for this video because we're gonna be bringing back block vote that's right from the series Blockheads and this version of block vote me writing it in the JavaScript SDK so those of you who know JavaScript you can build a full decentralized application from the ground up by watching this video with that let's Jump Right In and get started so what are we building today we're building the application called blog vote and in blog vote you can clearly
- 0:34
vote between two candidates here here we have a puppy and we have a little kitty and every user in that comes on and signs onto blog throw engaged with a particular vote only gets one vote so each user only votes once and then after that they can't vote again on that prompt the results are shown to the user after they vote uh so we know there's no bias before voting you just vote in and then like everybody you see the results are by
- 1:00
um so this is the actual polling page this is the actual home screen where each prompt is listed and this is the form page where each prompt gets created Sookie enter your prompt here enter Academy names here and here and answer each candidate URL being the URL link to their image uh here I thought you just submit it and get saved onto your blockchain so yeah all of this will require writing to a blockchain and reading from the blockchain of various
- 1:23
information so let's keep going so things you'll need will be node.js yarn and visual studio code so node.js will come with npx which will let us start off with create new rep you'll see what that is in a minute but also let's install different node packages as well we also have yarn package manager which is what I mainly use and the one that's particularly used within newer examples it's also just another package manager
- 1:48
but it's also a way to kick off scripts within like your package.json file as well so you can either use node or use yarn either one would actually work in the visual studio code just the IDE that I'm going to be using for this particular tutorial I suggest you get it so you can follow along easier and some of the tools and packages you'll be using will be near CLI near api.js near sdkjs react react to chipmunk Riders a
- 2:12
new CLI is just a way to communicate within your blockchain from your terminal the new api.js is a way to integrate the linear blockchain connectivity into your front-end application or back in the node.js script near CLI actually utilizes near api.js to send you know to interact with in your blockchain as well so it's a fun fact and you can also and also moving forward we have new SDK JS so that's actually the library that's been using
- 2:37
to write our JavaScript smart contract that JavaScript contract will compile down to plasm get deployed on student account and let's actually um store logic and interface within your blockchain as well for our first head framework we'll be using react if you guys aren't familiar with react I'll be posting a link to a crash course tutorial video done by Traverse media it's really good definitely recommend watching it
- 2:59
um but yeah it's not this tutor won't be too hard to follow for the front inside of things so just follow along if you think you can um in the list of react bootstrap so there'll be no CSS writing for the front end we're just using bootstrap to make our lives a lot easier and react router to switch between Pages a lot faster so yeah that's gonna be the tools and packages we're using for this application
- 3:29
okay everyone so here we are in the project folder that I created the very first thing I want you guys to do is run create near app so it's going to be npx create near app at latest app at latest that's going to give you the latest version of creating your app which is the quickest way to start off your uh you know project when building on here um so essentially so uh here we have two
- 3:54
contract languages options so we have typescript and rust uh we're gonna be making our project with the JavaScript SDK so we're going to be choosing typescript and I'm going to be setting our front end as react it's okay so just go ahead and choose react and then it just gives us project name uh block vote JS Edition that should be fine hit yes or why to install dependencies and then just give it one quick second
- 4:30
okay so now we've successfully installed or run create um create new app so let's go ahead and enter a project folder so do CD block vote.js Edition so essentially what this comes with is a whole you know as a whole template for you to start off your smart contract or start off your decentrise application that comes with the template smart contract uh template front end just to get you going and some integrated testing just to get you started with um integrate with your integration tests if you want to if you
- 4:59
want to dive deeper into that uh looking at the contract if you go to contractsource and contract.ts you'll see a typescript uh smart contract so typescript by the way is just a dialect of JavaScript so just you know so hopefully it doesn't like freak you out too much uh so we're still writing you're still using the near SDK js2 maker smart contract so you can even make this in just pure JavaScript if you want to but we're just using uh we're just using typescript for it's uh its ability to essentially
- 5:30
deliberately set the types of your variables your parameters and your function outputs and more so just to make sure your projects and your functions are getting the inputs and outputs that they are expected rather than depending on javascript's Dynamic typing alone um so here in this demo smart contract all it's doing is it's storing information onto the blockchain and retrieving that
- 5:55
information it's a very very simple smart contract so you can see how here we have the message messages of type string which is set to by default to hello we have this get greeting function which retrieves that string and returns it out into your application or your console or whatever you want just be able to manipulate it so you're querying the blockchain to retrieve this information and then you have set
- 6:19
grading which simply stores or modifies that message so this is the default message and this function here can modify that message um into if you go up here we can see four imports from your sdkjs you have nearby gen think of that as a glue for your smartphone for your smart contract set the near blockchain knows how to read your uh your JavaScript smart contract uh we have the near import here which
- 6:43
comes the whole slew of tools uh here here and ready for you to um help you with your smart contract writing so you have block height the current account ID you can get the name of the current ID the center County D the name of the signer you can get you can do near log which is essentially just like console.log to return a message to the uh to the console and salsa for event writing too and you can also get things
- 7:07
like a random C generators you can return like a random string or random bytes um just if you need some sort of random implemented into your smart contract so it's a whole cool set of tools ready for you to write your smart contract and then we have the call and view decorator so on near there are two different things you have the call we have call methods we have view methods so call methods simply change or modify
- 7:30
information onto the blockchain on the blockchain every column method that you run incurs what's called a gas fee so like if you which is essentially the amount of cost that goes into processing this transaction so people are paying for it's typically very very small on year and then you have view methods which is just pulling information from the blockchain so it's retrieving information from the near blockchain V
- 7:55
methods don't incur a gas fee so you can essentially call them as much as you want uh going to the front end as he that's really I'm sorry that's really it for a smart contract and going to the front end we have um app.js which is where the most the bulk of this will be designed um and we have uh the near wallet.js and next thing I want to show you um so this actually shows you how to implement the near wallet selector which
- 8:20
is going to be kind of like the main way people are going to sign into your application when building on here it's essentially a way to like uh like uh you know open up a wide variety of different wallet options to your user so um we're not just limited to the near native wallet so if you go to the near wallet selector GitHub repo you can see a whole slew of options for you to choose from it's really really cool
- 8:43
really handy uh in this demo we're only using two of these options which is The Ledger two times your application and the actual mind your wallet so which is the native wallet for uh kind of like the native wallet for near I used to be like well done here com but or dot org but I know it's mind your wallet.com uh we also comes when this also comes with a handy sign in sign out method which I'll show you guys how to use later and also this like uh template for
- 9:08
the for view methods and column methods essentially this is a way this is just a shortcut to allow you to make call and view methods uh sorry uh function calls to uh column methods review methods much faster than you know normal so I can simply comes to write write all this stuff out like over and over again to make your caller V method you can just like pass in these like simple parameters you see here and then you
- 9:31
know you can make your uh your method call if I were to run um yarn deploy that's going to compile my template smart contract and then deploy it onto what's called a developer account developer account is simply just a you know an accountant that's Auto funded with 200 test tokens it's meant to be disposable so you can you can do it whatever you want with it you can throw it away you can deploy a new contract
- 9:54
onto it you can modify code existing on it and you know you can make a new one if you want to it's meant to be disposable so it's perfect for testing perfect for uh you know developing um and then uh also um yeah so we're we're building our smart contract that's getting compiled down to wasm file that wasn't file is going to appear here in this build folder so uh pretty soon we should see a
- 10:18
hello near dot wasm file once this is done building I'm sorry my computer's kind of kind of slow with all the stuff I'm writing right now okay so we can see that the smart contract has been successfully built and deployed uh make this a little bigger for everybody um seeps there we go and we can also see the name of the developer account that it was deployed on to use we have our developer account here you can see our smart contractors has been deployed now after we've done this we can go ahead and run
- 10:51
yarn start and that's going to essentially run run our application so that's how you actually like spin up our application so we can see pretty soon cool um so we have like so we have our smart contract here obviously we have our application laid out in front of us here so we can modify this greeting we can view the greeting here we can sign out we can sign back in uh this is the actual like my the near wallet selector
- 11:25
that I mentioned earlier so we have my near wallet and Ledger as our options so I'm going to click my near wallet and it's going to send you over to testdent.mine your wallet.com which you should take a minute to uh you know create your test net account so go to testnet.minierwild.com that's going to egg to you in this like process white Builder application um so I'm going to hit next to sign into application hit connect
- 11:49
and there we go we're all signed in I can go we can see that default message hello remember that was our default string that we said earlier and I could say hello world hit save and you can see how the contract will then say Hello World um so yeah it's a very very simple application but yeah that's essentially everything you know about uh speed up the app and uh create new app and then getting started with our template so then we can use this template to then
- 12:19
start our block vote development foreign application we saw how to spin it up now let's go ahead and actually start developing our own application so let's go to the contract folder and go to Source go to contract.ts and then here in our here's we're going to actually write our JavaScript smart contract before we do so let's import a few more things we're going to import the unordered map and an unordered set and
- 12:55
under these are called collections in here so these collections are essentially just data structures um like like a normal like uh you know like map from like python where you have like a key value period that's what map here is we also have a set which is essentially just like a vector but with everything in that Vector being unique and then we also have things like actually like an actual Vector collection too so uh the reason why these are beneficial the reason why it's
- 13:19
beneficial to use um these collections over like the native JavaScript data structures it's because these are designed to be more efficient for the blockchains you can actually retrieve information much faster and much more uh much less much less much less costly um manner than like using like an ordana normal data structure on on JavaScript um uh let's see so uh that's really it for imports uh near bindgen we're not really going to um like modify here maybe it's
- 13:49
like we don't really need to do anything the only thing other thing we could do with it honestly is like say require init uh this would mean like we have to like we would require um initialization function for smart contract but we don't really need that uh so we're going to delete this um let's see and we can get rid of this like message for hello New Year and can actually keep these two things as a template if you
- 14:13
want to sometimes I like to do that um just so I can remind myself how to format and structure my change in view methods and uh let's see and actually we're going to do is move this call method like up here because the very first thing we're going to be writing out is our call methods I shouldn't say the first thing the second thing we bring is a call methods um but okay okay so enough enough formatting so we're we should be good to
- 14:44
go here um so we import our collections our collections are the unordered map and the unordered set so now we actually have to use them so uh first thing we'll be doing for our JavaScript smart contract for this voting application is keeping is a establishing way to keep track of the candidates for each poll so we're going to make a so do candidate see candidates I can't spell candidate pair used
- 15:18
store candidate names and URL links so when you're using an unordered map to keep track of our candidate names and then these URL links I just mentioned are just going to be for their images so the way we're going to do that is by storing an array of an array in um as the value tied to the key which is the prompt name for a particular poll so again the key is a property for the poll and then the value is an array the array will have four elements in it first
- 15:50
element will be the first candidate name the second element will be the uh candidate your candidates your URL for their image for their picture then the third element will be the second candidate's name and the fourth element will be the second candidates uh picture so to do that we just simply say candidate pair is equal to new unordered map string array so essentially what this is saying is that in this underword map all the values
- 16:21
have to be string arrays so this will accept numbers as value this won't accept anything else is a value or as normal string is a value this will only accept string arrays as values if you're coming from the rust SDK you know you may be you may be wondering like oh do I have to like establish the name of the key as well well no in the drops of SDK the keys are just strings and then you can just like establish
- 16:45
these values as uh as your desired type um so candidate pair so this is called a prefix this thing inside of here this is simply just so the blockchain recognizes um it can differentiate uh different collections within your state so um essentially that just me all that means is that all it's fours is to avoid data collisions within the blockchain when referencing your state with pulling information from your state so it helps everything you're blocking to identify
- 17:16
uh this collection of information faster prompt set is next so uh so prompt set is simply just going to be a way to keep track of the prompts that we can we're going to be using for our Pro there will be they're going to be uh created in our application uh each prompt could be like what's you know what's better a dog or a cat or who's stronger Luke or Darth Vader or something right so like uh each of these will be let's see unord set
- 17:53
will be a prompt so there we go vote array um yeah that's fine so next up is going to be a way to keep track of our um of our vote counts so every vote will be counted will be kept in an array the first indices will be for the first candidate in the second industry will be for the second candidate so pretty straightforward so vote array is equal to new unordered map number vote array and hopefully you guys are seeing the pattern last collection this is the last
- 18:47
one uh is just keeping track of user participation so all this does is keeps it's all this next collection is for so keep track of user participation within a specific uh prompt right foreign so the idea is is that we're going to be storing uh new on the word map is that we're going to be storing um the uh vote I'm sorry the users names in a string array tied to the key which is
- 19:29
the prompt for that uh vote that they took part of um so user and then essentially we're gonna be using the uh kind of like the convert this so we're gonna use this array to use the includes method with that array to see whether or not their name exists within the array which will then give us a Boolean back letting us know that um hey this user has voted before we can't let them vote again in
- 19:51
this particular poll so that's it for our collections uh so now we can move on to our call methods so below our template call method Let's uh create our first one our very first one is adding the candid pair to our very first collection here so candid pair um and actually before we move on let's change this let's change the hello near to voting contract just so we know what this is for so at call
- 20:29
add candidate pair um see so uh the way arguments are formatted in this typescript JavaScript contract is a bit weird so just bear with me um yeah it's gonna be it's gonna be it's gonna be it's gonna look a little bit intimidating but once once we get started you get the flow of it and then you get used to it it's not it's really not that bad so first thing we'll be doing is just giving our argument a name
- 21:01
right so we can say that this first argument is named prompt and then um and after the first curly brace right uh actually you should know this I should I didn't mention this earlier but I'm storing my um I'm storing all my arguments in like uh almost like an object instance right so like we have this like object instance here where I'm like listing the names of my arguments and then after the closing curly brace I'm putting a colon there and putting
- 21:27
another uh curly brace here um to then give this student a sign a type to this prompt or to this argument so I can say prompt is of type string so that's what kind of looks like so like yeah we have our first we have our argument name which is prompt inside this uh inside these curly braces a colon separating two and then another set of curly braces defining the type of this argument so
- 21:50
um again this is typescript typescript's a bit weird but and this is supposed to be it and but this kind of like deliberate fashion is going to help us make sure that uh our types are what we expect them to be um so first prompt uh and of course again you don't have to write this in typescript you can write this in JavaScript if you want to but I would recommend uh that you write your smart contracts in typescript so you can be
- 22:13
more deliberate with your uh with your parameter and argument types other than that again it's all mainly the same thing so name one name two so we have a prompt we have as our key we have name one name two URL one and then URL two right so then in our second set of curly braces this is how you actually put in more than one argument by the way I didn't learn this when I first learned this about this SDK so uh try and save you guys the same Patek I ran into
- 22:45
name one string name two let's put it into break here name two string and then um I forgot uh URL URL one you don't know what that actually might be fine okay I guess it just wants that okay so URL one string and then URL to string cool okay so this is this is the the big the only function with that many arguments I swear um but hopefully this helps lock in the pattern of how to create arguments within typescript uh so let's just keep going uh the actual body of the function is
- 23:35
not nearly as bad right we're just saying this this dot candidate pair dot set is of type prompt and we're storing that type problem sorry has the key prompt and restoring name one URL one name two the URL two inside of this array and that's it so you've successfully ran your very first uh change method in your JavaScript in JavaScript smart contract so good job guys so let's just keep
- 24:12
going so we have so our next one will be at call right so for every different column method we put we have to put this decorator if everyone goes inside of here by the way um all that's inside of here is either is a Boolean for private functions we can change that to True saying that this function is private or making this payable which we can also set to true um if this is payable all that means is
- 24:37
that is that this particular function can accept a deposit and deposit is simply um an amount of near you're sending it directly to the contract account or the contract that's hosting the uh or the account that's hosting the contract um and that's it if you don't put this if you don't put this payable and you try to attach a deposit it'll throw the the network will throw an error next up is initialize votes
- 25:01
argument will be prompt all this does is as it says we make a new prompt we have to initialize the vote count for it prompt string and then uh so sorry so this correction this dot vote array dot set prompt um and that's it Oh and before we move on I made a mistake put a colon here instead of a comma that probably would have caused me a bunch of headaches later on uh let's see prompts uh and then after that we do we
- 25:48
set this default value to 0.0 okay so then let me just re run through so we have our column we have our call decorator for initialized votes which accept the prompt is an argument of type string and we're simply setting that prompt as the key and the value as zero and zero because we're just initializing the vote count and that's really it so let's just keep moving on so call remember currently remember to include that call decorator
- 26:18
and then we're going to be adding so adding to prompt array so uh in this this particular function all we're doing is we're adding this prompt to the list of prompts in our set so we're going to say prompt prompt is of type string you can see that the prompt is gonna it's gonna it's gonna be like the main key here no pun intended okay maybe it was a little bit intended uh prompt set
- 26:49
set prompt so let's just step back because I want that direct kind of fast so prop set remember we Define that as our set which is an ordered set and then this unordered set comes with this function called set well I'll just hit set so many times like um we're set here for uh for vote array which is an under map right so vote array it's just the vote array is not really an array it's probably poor naming but like vote it's just storing arrays in this unordered map uh but uh maybe like candid pair right so candid
- 27:22
pair is an under map and this unordered map comes with the whole slew functions including dot set or unordered map um uh simply uh under the underword map set simply has a key sets your uh sets a value to a key right so we have this value we're staying at two key in order to set also has a set function but instead we're just adding this value to that set that exists so that's set by
- 27:46
the way again it's just an array with unique values like Dorian one and then Dorian two and then if you try to do during one again it won't let you right you just say like during whatever exists in here because it's just a set um so that's all it's doing it's just adding that prompt to a set at call let's see next one will be clear prompt array this one accepts no arguments because all we're doing is erasing everything so this will clear um clear the sets clear the prompts
- 28:28
clear everything so we're going to say this dot prompt set dot clear it's also come the set and Maps also come with a clear function so that's pretty handy this dot candid pair dot clear cool this dot user participation dot clear great this dot vote array dot clear it's just again this just simply empties out everything inside at least inside these collections near that log remember near log I mentioned earlier it's just like console.log so we're all we're going to
- 29:01
put is clearing polls you know so that just clears the uh this lets us know that this actually worked in that it's a that we cleared everything from all these collections next is at call there we go next up will be adding a vote so this is how we actually add a vote to um a vote count uh so remember our vote count is going to be stored in an array right as we established here earlier so this vote count will then we have to
- 29:35
first uh pull that array we'll be pulling that using the key which is the prompt name and then we'll be selecting which part of that array or which indices we want to add add one vote to so for which candid right so we're gonna have to use an index here as well so in the prompt is going to be of type B what you know you probably guessed it yep it's going to be a type string and then after that
- 29:57
index will be of type number so yeah we get that okay cool um so now let's just first you have to uh pull our vote array or vote count right so we can say let current votes equal to this dot vote array dot get so get is another function for a noted Maps so get and now it's accepting a key as an option so we're going to put uh our prompt is our key and then if uh so now here's the fun part if this prompt does not exist right
- 30:36
we could say if we wanted to we're not going to we could say um you know here's we can just say here's a default value add you know add zero or here's a default return value for this get so again if this key does not exist we can just return it to empty array we might as well actually just keep this that's actually fine um so either way we're going to get something back from this function we may not want that but I'm just gonna do it for now let's just show you guys how to do it um so I'm going to say current votes
- 31:08
index current votes index and plus one so what am I doing if I want to vote for uh the second person right right if I vote is for candidate number two then zero zero candidate numbers two vote will be the second zero here right um so that will be of Industry one so for index we would pass in a one if I want to vote for the first candidate I'll put I'll pass in a zero for the index value and the index value is going to be referencing this this uh first zero here so we're saying uh let's just say for the second candidate that's
- 31:47
the index of B value of one so we're using that we're saying that um select this this second indices or a second uh element and then take the existing that second element and add one to that so that's all we're doing we're just adding one to that current value that exists within that second element so just to keep moving forward um so this dot vote array dot set prompt oh my gosh current votes so now we've updated the value so now
- 32:20
we're going to take that newly updated value and uh overwrite what we we had before in the blockchain so we're setting that prompt to this new current votes or to new update current votes value and that's it last call method is simply for recording the user let's record user prompt user colon prompt is of type string users of type string um so recording the user so how does this work essentially we're going to say let current array
- 33:08
uh we're going to like pull in the current uh list of people that have have taken part in a in a poll or particular part in a vote is check if that person exists within that um array and if they don't they're going to add them to that array so then we can keep track of who has and who hasn't voted in a particular poll so this dot user participation dot get prompts and then default value foreign so if no one's ever voted in this room in the history of the world then it's
- 33:47
going to give them a new empty array current array dot includes user so this next line is going to be a ternary statement or conditional statement so it's like writing an if else statement but in one line so like if this current array includes this user if if the name if the person's already there and then do nothing if the current rate does not include the user then we're going to add that user to that array using the push method so push user
- 34:19
that's it after that we just say this set user participation dot set right we're setting that newly updated array to prompt current array so again if that um if a user if a user does not exist or if the user does um does exist in that or List already then nothing will be added to the array we're just going to be pushing in the exact same array and that's it for uh for our column method so great
- 34:51
job guys like like fantastic job next up will be our view methods so every methods uh won't be won't be that bad um no there's not too many of them so sit tight so at view same thing uh get URL was our first one maybe this one's the worst but not of all of them I tend to like to put I like to put the first ones for uh early on prompt name uh then prompt string name string so for view methods unlike call methods view I mean this is injury but review
- 35:38
methods you have to return something for call methods you can but you don't have to return anything for view methods we're going to be returning a string or for this particular for this particular view method we're sharing a string uh we're gonna say near that log because we want to get the URL right so that URL is going to be of type string so near log prompt that's just letting us know what prompt we have into the terminal let's candidate
- 36:04
candidates URL array equal to uh just you can't array they're CAD array equal to this dot candidate pair dot get prompt and then return candidate you or candidate array and then um here's the fun part okay so hopefully I'll lose you guys here but hopefully uh pay attention here uh so we're gonna say candidate array index of name plus one so what did that just do right so um I'm sorry I think catching something uh
- 36:50
so let's take a step back and see what we're doing here so we have you know name one URL one name two URL two put all this in a comment so it's not giving us its weird lines um so if we want the URL right get URL as our function creating if we want the URL the first candidate we have to pass in that candidate's name so uh I mean I guess I could just ever yeah so uh if you're passing the Canon's name
- 37:21
we're gonna say okay we're gonna be referencing this first candidate here next to that that's good next to that is the actual URL that's associated with them right so that's just how our function was ran up there so that's how we know it's going to be a you know uh we're gonna match that time down here so we're saying get the index of the first candidate and add one and then like pull that information out of that second like uh element so that's all we're doing
- 37:45
here we're getting the element of the first name and then we're adding one to get the element of the URL that's all that's happening here hopefully that makes sense um you can always let me know if you guys like get lost in the uh Discord chat uh that's it for our first view methods of your very first few method good job guys next up at View did participate is our next function
- 38:19
prompt user prompt string user string and this will turn a Boolean remember we're just checking whether or not a person has ever taken part in a particular poll in the past if they have we're going to return a true if they haven't we're going to turn your false so we're gonna be using the includes method uh that comes with uh see that comes with arrays to make this to determine whether or not a person is taking part in a particular prompt or not so we're gonna say let um
- 38:56
prompt appear on PT uh user list string there we go equal to this dot user participation dot get prompt and then we're going to say our default value to an empty array so remember we're just getting the uh we're just getting the list of users that have taken part in a in a particular uh poll um if not if that poll does not exist or if there's no one if there's no in that poll we're just gonna return an empty array after that we're going to say we're just going to say return
- 39:35
prompt user list dot includes and then user so what's happening here remember this is an array this value will be an array of strings to even Define that value right here so we have to imagine that that array of strings comes with this method called includes that a methical includes will check for whatever you pass in and see if that if that value passed in exists with an array and
- 40:00
return a Boolean so then we're in fact what's kind of fun is like if I didn't return a Boolean then this like functions of scream at me it says Hey like this function wants a Boolean as a as an output what are you doing so yeah anyway so you can you can kind of see the handiness of typescript it's telling you it's it's defining that we want to Boolean so make a focus gets a Boolean which is perfect because that's what we also need
- 40:25
um and that's it uh so at this next step is what if we want to view the entire list of people who have already taken part in a particular poll so we're gonna let's make a quick voucher for that we may not use this one but I like I found it handy when I was debugging so I'm going to give it to you guys too participation array prompt prompt string and this is going to return a string array because we're getting a list of people who have taken part in a poll so we're going to say return this
- 40:57
user participation dot get prompt that's it so next up is what if we want to get the entire list of prompts so this is a very I think this is actually pretty important like uh like function to learn it's very simple but I think it will come in handy if these guys you guys want if you guys want everyone to use like underword sets so just say you want to return everything in that set right well you can with this function you can say this that prompt set
- 41:30
1.2 array so it's going to convert that set into an array and let you and return it to you so this I can get everything your entire array listed out for your function if you ever needed that which I think comes it comes up quite often and that's it next up is at View uh get votes so if you want to get the votes for a particular prompt so it's a prompt prompt string number return
- 42:14
this vote array dot get prompt default value so what's happening here so yeah we're getting we want to get our votes our vote is a pro is an underword map which which uh whose key are the prop names so using the get function passing the prompt name and then we're going to be returning the array of votes for that particular prompt if that prompt does not exist then we're returning an empty array that's all that's happening here some last function last view method
- 42:47
few but okay great get candidate pair prompt okay what is this property of type it's gonna be type string then whatever you're turning from the skate candid pair because you want to get the candid names right the names of the two candidates a string um so same thing as uh same thing as before but we're gonna actually what's kind of funny is I I kind of did the fancy way before it
- 43:20
probably could have been a much easier way uh looking at the way I wrote this function but it's okay we're gonna keep going so let candidate candidate array uh equal to this dot candidate pair dot get uh prompt this is actually a much easier way to cover it in the very first function but I like to have fun sometimes uh let's see default value and slash a comma and slash a uh so we're checking for a candid pair if that if that prompt does not exist for a camp pair there's some returns
- 43:59
empty uh this uh oh well okay this is actually it's weird um actually we don't really need this default we don't really need this default function for this one actually yes just do it let's just keep it okay um just add two more of these there we go so um if this project exists we're going to get an array of of not available
- 45:03
name URL right um where the first arrays of cat is at count zero uh and yeah that's essentially our entire JavaScript smart contract so great job guys you just wrote your very first JavaScript smart contract let's go ahead and see if it built or if we can build so you're in build that's going to build our smart contract cool so it built out uh both our contract and our front end uh successfully so we can go ahead and run yarn deploy that would actually find enough build our build our smart
- 45:41
contract again which is okay um but it's also going to deploy a smart contract onto our developer account cool so we've deployed our very first smart contract onto the developer account great job guys okay so now that we're in our smart contract let's go ahead and go to app.js let's go to front end right so it collapse this front-end uh folder at the JS and let's build out our front end so the very first thing that we get to do is take everything past this first curly brace
- 46:20
and just delete it yeah that's right just get rid of it then hit save and then Within These curly braces type in return and then uh div hello world and go and type in yarn start that's going to spin up our front end let's see you can get rid of that you see hello world uh I put that was a typo sorry hello world there we go hello world uh right here go ahead and delete this like level.css line right so just delete that Global CSS line it refresh
- 47:03
the page you should see like a really nice blank template here and now we can go ahead and add our styling so type in a CD front end so make sure you this is very important but make sure you you change into the present folder go to react bootstraps made website and go to the getting started page type a copy of this line versus npmi react with trap bootstrap or just type it in yourself you have to copy it necessarily and then just install it
- 47:27
within your front-end folder while it's installing go down and copy the CSS line and paste it at the very top of your page so we're going to say react bootstrap and just paste that CSS line there after that go to react router just Google react router quick start so we're just going to do it right now so react router quick start and then go to the very first link you should see this thing here it says yarn add react router Dom
- 47:57
let's go ahead and do that let's just do a yarn add react router Dom and paste it in here make sure you add that first why like I you know series is taking the show um make sure you type in uh yarn add react Rider Dom in your front end folder or npmi reactor Dom should also work um so either either one should work so uh they aren't add react router Dom um and that's awesome so let's close that now let's go back to
- 48:39
our uh our um our react router page and just like copy and paste this entire import line here with all the browser router as router switch route and Link um lines and then just go to uh your page bootstrap and then add another cut section for um react router so we're gonna say react router right here support this statements and just leave it alone for now um and then so now it's inside return statement inside of instead of uh you know the devs gonna put parentheses here
- 49:17
and put in a router right here we're wrapping this wraps our entire project in this router line so that way we can um we can seamlessly switch between components that we either include within this router uh with this within this router wrapping um so go back to react bootstrap and let's get started our very first component which would be our nav bar so type in navbar into your uh into the
- 49:42
search into a Search tool and go all the way down to where you see uh where is it where is it where is it here it is we see uh kind of like this responsive behaviors uh section so go ahead and copy just copy everything inside of navbar and we're going to clean this up to make it like a little more um custom for us paste it inside of here hit save and then um instead of here if you go back to our uh
- 50:12
our page if you hit refresh actually just run yarn start again you can see this actually imported properly and it looks okay uh oh because I forgot to import our navbar stuff so that's that's my bad go back to uh react bootstrap's website and just uh just kind of copy and paste you see everything you see here paste it inside of your reactory trap section we'll go back to our home page and we should see and that's great so we can see our nav bar up here here um so if you've imported these
- 50:49
statements you've imported the CSS you've pasted in that template react bootstrap thing then you should see uh this page up here which is good um so now let's actually customize it to our to our liking so um things we don't need we don't need the features pricing or drop down menus so we can go ahead and get rid of those so uh everything everything you see yeah so uh features and pricing get rid of that um nav drop down uh get rid of that everything between these net between
- 51:21
that including these uh nav drop down tags just get rid of it you can leave this a nav class name me auto loan because that actually provides some really good spacing for us so you can see it actually maintains that spacing if I were to get rid of this empty thing if if I were to get rid of like empty line here uh you see like those things move over to left which I do not want right so I want those back to the right so we're going to replace that here it says more Deets just replace
- 51:47
that with new Pole it's a new pole and here where it says dank memes replace that with login now where it says nav bar dot brand get rid of react bootstrap and replace this hashtag home with the forward slash and then after that uh create an image tag inside this image tag type in Source inside of source inside of curly braces uh type in and you can copy this from the description as well type in HTTPS colon forward
- 52:20
slash forward slash I dot imgur.com this is gonna be the logo then slash three one dvjnh.png hit save uh remember to add that closing tag hit save go back to the home page and we should see our blog vote custom logo up here here I made this using figma actually so um we've already like we're basically going like the the appearance of it but let's actually make these uh these Keys functional so um here it says hashtag diets replace that
- 52:53
with forward slash new pull and for the extract login button we're going to remove everything we have here and just replace it with an on click uh before we even do the on click let's let's make the function for it to actually uh call right so um above your return statement I want you to type in um const sign in function equals and use an arrow function and then just import um and just say wallet DOT sign in where's this wallet coming from it's coming from
- 53:32
this automatically imported line here into your props right that those are being sent in through your index.js file here where that wallet is being instantiated on line 13. so if you're running red came from that's kind of where it came from it's all coming from it's all it's actually originating from your near dot near Dash wallet.js that's where a class is being defined um so going back in we're also going to make a sign out function so say const sine out function
- 53:59
same thing Arrow function and just say wallet DOT sign out and now in your uh login file we're going to say um let's see we're going to say nav dot link on click is equal to is signed in if you're signed in which is true then sign out right it makes sense so sign out function if you're not signed in then run the sign in function so if you haven't seen this format before it's called This is called a ternary conditional statement so ternary conditional statement with these types of statements it's just a way of writing like an if else
- 54:46
statement but in like one line so it makes a little more convenient but typically it's better to write an if else statement because they're clearer than this in most cases but this is okay for now so we're just saying if the user is signed in question mark then run the sign out function if the user if this is false if this this isn't really Boolean here by the way so if this is false then
- 55:07
run the sign in function so if it's true do this if false do this that's all that's saying hopefully that makes sense here we go um so we're gonna make you're gonna use another one of these for the actual string here too so we're gonna say is signed in question mark then display the Wallet account ID or the name of the person that's signed in otherwise just display the string login great so if we go back to our page we
- 55:42
can actually click on this button you can see that I'm already currently logged in so it's going to log me out if I log in I can see the wallet selector appear here hit mine your wallet and go and sends you over to testnet.minderewell.com also again if you haven't made that account on testament.mine your wallet.com go ahead and do that after that just hit next and then hit connect and then we should be all signed in and there we go so we know this actually
- 56:07
works if you hit new pull we should see this URL change and you pull and it's actually linking to anything yet so uh we have to make that uh and we're going to like right now actually so um we're gonna create this little function called const display home this is going to display um our home page and be where we're going to navigate between different routes so we're going to say if is
- 56:38
signed in then return parentheses routes uh there we go okay so import routes from uh from react router Dom there we go and then within routes type in you can actually hear the switch statement I can use that type in um route foreign the home directory so we're saying if our URL is guiding us to this particular path or this endpoint uh display this element and this element will be a home tag
- 57:37
and you're wondering hey where is this coming from and then well then you'd be right because uh we tried to import that right uh we forgot to actually create those so let's go ahead and make a new folder in your front end and type and make that call that folder components and within that folder we're going to create three different files one is called home.js another one that's called new poll dot JS and then another one that is
- 58:04
called pollingstation.js in each one of these we're going to type in I'm going to use my react Snippets extension to to get my to get my starting template here you can just go ahead and copy this on screen so we might want to pause the screen for this if you don't have react Snippets um installed on your vs code otherwise you should get react Snippets um so we have our home page we're just
- 58:27
going to type in home for now it's like this div here we're going to say same thing as rcsp uh again that's a feature from react snippet so if it's not working for you that's it's just an extension that I got from like this little button here right um so a new poll could just be new pull for now and then polling station rcsp will be get rid of these prop type things we don't really need that import as well we're just going to call this polling station there we go so going
- 59:00
back to our app.js page we can continue on with our with our element right so home oh actually we need to import these two uh so below your react router Imports uh make a new section called custom components and then import home from react from components at home so should Auto autofill for you which is kind of nice um next next step do import uh new poll so new poll and then after that import polling station and hit save
- 59:41
and then um now we can finally say home forward slash end and then after that uh just close this tag to get the route and there we go this is our very first uh component that we're importing but we're not done yet we're very far from done so um keep stay hang with hang in there with me guys it won't be too bad uh next route will have the path of Slash new poll then the element
- 1:00:12
will equal new poll there we go then after that we'll have the route with the path is equal to forward slash polling station and then the element will equal you guessed it polling station oops closing that hitting save if I go back to our page and if I were to uh let's see refresh what should we see we're going to go back to your home page first and I say these components let's see
- 1:01:06
save save save oh I know what's happening we never actually uh exposed this so below your nav bar blow your nav bar remember to call display home function so we're it's going to look exactly exactly like this So Below the nav bar make some curly braces that's going to prompt you to view some GS jsx which is just basically JavaScript um and then just say display home and call it call that function below an FR and hit save and now if we go to our home page you see if you see the word
- 1:01:45
home here if it was a new poll should see a new pole up here here if I were to type in polling stations since we have a button for that yet we should see a polling station appear here um so great this is essentially the fundamentals for us getting started uh this lays on the groundwork of everything else we have to do all we have to do is like populate these three components um
- 1:02:08
it should be on our way but before we move on to the next section we're still not really done with our display home function um so we're so we only wrote the if right but what if what if you're not logged in well let's just make a message for that so we're going to make an else we're gonna import a few more things we're going to import um uh from react bootstrap there we go import a card a button and
- 1:02:39
a row all from react bootstrap so else right so we have our else section to complete so if we're not logged in if we're not logged in right um display we're going to say display this container then that container will have a row with a class name of justify Dash content Dash Center D Dash Flex close that in that side that row we're going to have another one of a card with a card we have a style of margin top
- 1:03:27
5 VH with of 30 VH um vh's view height we can do view with but it doesn't it's okay it'll look fine within that card type in container and then within that container type in another row with the message it says hey there uh please sign in and then below this row we're gonna have another row oh my gosh whatever um there we go uh we have another row that says last name is equal to
- 1:04:14
justify content Center D Dash Flex and that will have our button telling the user to log in and that button will only have we don't have to do any fancy ternary statements for that it's just a simple button that says on click run sign in function function there we go uh and that's really it so let's test it out so we're so we're back at our home page right we're logged in but if I log out um let's see
- 1:04:52
what is happening oh uh be sure to wrap everything you see here within a return statement uh and get rid of this semicolon there we go so wrap everything within the else statement Within These elf with it's like wrap everything within the else curly braces into return statement so the entire container goes into a return statement so now we should see this cool little message here we can probably format The Styling a little bit more if we want to but for now like this is
- 1:05:22
totally okay so we can see like hey there please sign in we can click this login button and hit mind your wallet and then we can like go ahead and use the application um and actually uh I'm just saying again for this but like you can even see when we log out this new pull button uh it should we should probably disable that right if we're not currently logged in so we're going to um
- 1:05:47
go down to where it says new poll and then uh just type in disabled and inside of a credit breaks type in uh exclamation point is signed in so that means like if we're signed in if we're signed in this will turn false because the exclamation point so this will be true this explanation point makes it false meaning do not disable but for not signed in this will be true this expiration Point uh will
- 1:06:18
turn like uh we'll turn that like I'm sorry if we're not signed in this will be false this expiration point would turn out to a true and then that will just mean like we can't use this button right so now it's button's disabled for us so essentially um the groundwork for app.js um we I think we still have a few more things to add in the future but for now we're gonna leave it as is so good job guys
- 1:06:45
okay so now that we've uh laid down the foundation for our project we can go ahead and go into home.js to actually start like populating our home page so very first thing I want you to do is to uh you know like establish your Imports um so let's go ahead and import a few things from react bootstrap so type in import and then type in table and container and button and finally row oh I'm sorry ant card
- 1:07:18
uh all from react bootstrap so there we go next thing we want to do is um just makes a few State variables so State variables are essentially variables that will um you know that you can you can pull into your component and when you modify these State variables your component then reloads so they're kind of useful so you can type in use state um there we go uh so you know there's a
- 1:07:48
few things I want to do there's a few things I want to do on this homepage so this home page will essentially be for um laying out your entire uh all your prompts and all your um all the things that your users can get involved in essentially so uh the way we want to like actually do that is by first retrieving all the prompts uh that exists within like our blockchain right so luckily we have like we have a blockchain method for that and we
- 1:08:12
incorporate that blockchain method into into our home component so first some State variables um so do const disable button this will come back we'll come back to this later so disable button and then change disable button equals to use state this will just this will come in handy later so don't I'll explain what this is for in a minute uh next step is const prompt list so prompt list and change
- 1:08:52
prompt list is equal to use state so let's go ahead and actually create um sorry parentheses bracket create our like our visuals for our homepage and show you guys what we're doing so to display our components we're gonna go ahead and go over to um react bootstraps website and look up table this will give you an idea of what we're actually making and this is it actually so we're going to use this table to display our component so it's pretty
- 1:09:22
cool right um so in order to do that we're going to say we're going to go to a return statement throw in some parentheses go down say container and then go down and say table style is equal to margin 5 VH then striped bordered and hover I think I misspelled stripe they miss well striped c-r-i-p-e-d no and then sorry uh there we go put that in curly brace here there we go so striped bordered hover after that type
- 1:10:11
in t head this will be where headers are contained inside of T head type in TR that's going to be the first row for our headers and save that type in th that's going to be our very first header so we're going to have a hashtag it's already presenter similar to what we do here so hashtag is our first header and these are any and these hashtag just to notes all the numbers below it next header will be the list of pulls so type in th
- 1:10:35
th and then list of polls and then after that type in th and then go to pull and that's it so if I go back to our to if we go to our local host and type in hit login right we're going to log into our application okay go to your home page you should see our table starting to appear here so it looks kind of cool right so we're actually building this thing off let's actually see it I'm getting built out so th that's stiff for the head right uh so I'm going to type in t body
- 1:11:24
it's gonna be okay so now we've finished with the head of our table let's focus on the body um so very first thing I want you guys to do is go over to uh is go over to like your prompt list and put in prompt one and prompt two within that array that's going to be our dummy prompts as we uh as we fill out the body so we're going to say prompt list and some in some jsex prompt list.map
- 1:11:49
element and index map is simply a way to iterate through an array and uh perform some Logic on each element so say if prompt list if this prompt list exists right if we if we have some if we have a if propless not length right um if there's some sort of element within this array then we're going to do something so we're going to return TR I is equal to index that's a react thing we have to make sure to do that or also through an error and then
- 1:12:27
in this first row you're going to say TD not the first row but like each row we're going to return the index plus one uh that's just going to be our numbering system index indices start start zero so we have to add one to that to make this industry start one and after that um display the name so if I go back to our homepage you see prompt one and prompt two beer here with one and two so element is a problem prompt two and
- 1:12:51
index plus one is this numbering system here so that's where it comes from and after that we have to go to TD and then after that uh type in button and within button type in go to pull uh that should look like this so it looks pretty good so we have go to pull that button won't do anything right now we'll come back to a little bit later but yeah essentially this is going to be what happens when you actually display your page so it looks pretty cool right
- 1:13:17
foreign we've like successfully like made out like this like table here if we add some sort of value to that we can say you know prompt one then prompt two then for funds just put dog then we should see all those things be here and we can actually leave it you can even have a way to go to the polling for each one so um great job that's essentially the beginnings of our homepage okay so there's one more thing
- 1:13:47
I want to add to our home page and that's simply a little message that shows off that shows up whenever we don't have any uh prompts to put on display so um the very first thing I want to do is create a is create some jsx inside the j6 or have a ternary statement so we're going to say prompt list dot length is greater than zero if so do nothing if otherwise if it's not greater than zero
- 1:14:17
um they're going to display message so make some parentheses in those parentheses make a row with the class name of justify content ER Dash Flex card and the card will have a styling with from ABW height 10vh inside that card all I want to do is put this little message that says no prompts to show and then we're going to add one more uh so yeah if actually if we go back to our page oh my God it's actually if we go back to our page
- 1:15:18
and then go up here and just remove everything you see inside of this uh inside of this array make an empty array if we go back we can see some messages says no prompts to show so that's good so uh we did the right thing here um we have one more thing I want to do uh we're going to go ahead and toss in a new row right below it blur a little jsx and we're going to make a button called
- 1:15:45
clear poles width of 20 20 VH margin left 10vh thank you and then after that we're going to have an on click where I could do it just yet uh disabled disable button let's go to disable button and then inside of a I'm sorry was this still the row this is still the row um sorry uh take everything I just wrote here yeah okay let's just go back just okay so now we have our no prompts to show message done we're going to add one more button or one more row to this uh more feature to this page uh we're going
- 1:16:50
to add a row and inside that row we're going to have a button and we're going to have that button we're gonna give that button The Styling of uh with 20vh margin left 10vh and close the button and set the button just put clears polls so if we go back to our page we have this in the field button that says clear pose so obviously none of our buttons do anything for your add functionality a
- 1:17:24
little bit later but for now I say we move on to making a new poll foreign page uh you know essentially laid out for now we're going to come back to and fill in these buttons um we're going to make uh our new polling station our new polling page so in the new pulling page um this is essentially where users are going to be able to uh create a new Poll for people to vote on enter new candidates and uh yeah just essentially
- 1:17:57
add new polls to the um to the front end so we're going to go ahead and start off with our Imports so let's go ahead and import um and just like replace right we're just like wait there we go import a container form button row column and a card from reactivate strap and we're going to start off things by creating our state variables and let's see so first date variable will be I'm sorry uh not safe variables uh references uh these references will come
- 1:18:39
in handy later on so essentially the reason why I'm doing these references is because um candidate name one is because we're gonna be using what's called a form in a reacts bootstrap and let me show you guys what that is after I type out this first reference here we go so if we go here and go to um just like react bootstraps website and look at form we can see these uh forms here right so you can see it's like this example form
- 1:19:10
would be like I'm at an email add an add a password so how do we actually like make use of that email and password well we have to use a reference actually if I type in ref I think there should be one here somewhere okay yeah it shows you how to okay does it show you exact implementation of using reference we're going to do that here that's fine just shows you just tells you what a reference is um so
- 1:19:34
to pull out that information we need what's called a reference and in react it's called use ref right so you create a variable name and you give and you put into this uh thing called use ref and then you can actually use ref to the form field in that form field to essentially let you pull out the string data that the user types in candidate name two use ref const candidate name one URL is equal to use ref
- 1:20:11
cool I think if I do no I do option D there we go option D um I can copy that line that's handy um and then after that one more ref will be our prompt Rift so prompt ref equals use ref there we go these are all references now all suffers are State variables so if we do const disable button and then change disable that's going to come in handy when you want to when we want to submit our information so we don't have the user submit a bunch of the same information over and over again
- 1:20:49
so just that just disables the estimate button and then this next one would be const uh display message letting the user know when they can return back to the home page after their information has been uploaded to the blockchain uh change display message they both use state false um great so now uh before we do anything else let's go ahead and create our function our send to blockchain function just to get that out of the way
- 1:21:25
so we can say const send to blockchain and this will have to do a few things it's going to have to uh first create the candid pair and then after that it's going to have to um create the initialize a new vote add a new prompt to that prompter way and then after that sent all this to the uh to the blockchain so it won't be too bad um async we're just going to get through it so send to blockchain equals async this is asynchronous function every call and V method is asynchronous process
- 1:21:55
um so we're gonna put prompt um I'm sorry we're going to uh actually before we even do anything I just realized we still haven't done one thing yet so we're going to go back to our app.js page and do things or and do something that's going to make our lives a little bit easier when establishing um when utilizing these like column chain review methods so if we go back to our homepage or app.js page we're going
- 1:22:19
to kind of create a little cheat for um you using column view methods uh the reason why we're doing this cheat is because um the way these are written inside the the near wallet.js file um is done in such a way that makes it very easy to use when you're interacting with multiple different contracts but for us we're going to be interacting with one contract so we don't always want to have to uh pass in this like
- 1:22:43
contract ID name here um again if I were using word one contract then yes I'll just leave this as is and import from the nearwall.js but I want to do things a little bit differently and it's going to save us some time in the long run so I'm going to say const call method is equal to async um the async method name comma args where I set that by default to an empty object instance
- 1:23:17
and then we're going to say um const call method is equal to async I'm sorry sorry brain fart uh wallet there we go wallet dot call method um contract ID contract ID so remember getting that from getting that literally from up here so we're using this contract ID that's being passed into our app to a note to uh then pass it into our um first parameter for that contract ID method or contract ID argument next one will be method name so
- 1:24:10
we're going to put method and then method name such there's gonna be method to name we pass in from here um and then after that we're gonna say args args also another parameter we're passing in Next Step will be const and we can put in a weight on here too there we go um next up will be const uh View constant view method is equal to async method name same thing and you guessed it args is equal to
- 1:24:44
empty object instance um after that just put an arrow function we're going to say return await wallet Dot View method contract contract ID same thing contract ID we can actually probably copy these next two lines here just paste them here for us make our lives a little bit easier uh and get rid of this parentheses here I'm not really sure why we why I put that there but that's that's fine um that's really it so now we can go
- 1:25:26
ahead go to our little route section here and pass these in as a prop so we can pass these in as a prop so we're going to say for a new polling station or a new Pole call method is equal to call method hit save and uh after that we can then put uh add a new line we'd say view method is equal to you guessed it view method uh closing curly brace and hit save um and then after that we're gonna pass through one more thing uh we're going to
- 1:26:09
create another function that's going to come in handy for us while we're making this new polling station it's going to be called um const get prompts and then um so this function is really easy all we're doing is getting the complete list of prompts and that's going to come in handy um as we're like writing out our new polls you can say return weight view method get all props and actually this is using that function we just that we just created right so um is that kind of cool so you can see
- 1:26:50
how we have to pass in the Contracting we're just passing in this like function name and we don't mess an argument because like that's right with this particular function doesn't take an argument so now I can go here go to new poll and just type in get prompts is equal to get prompts there we go so now all of our elements will be essentially using this call method and view method thing so we can actually
- 1:27:21
just like copy these two properties and paste them into the other elements so let's go up on to your home and then just paste these in go to polling station and paste these in here so we can get ahead of ourselves a little bit um so go back to the new poll.js and then go to and we're going to continue on with writing our uh send to blockchain buttons a new poll.js send to blockchain button um so give me one second there we go
- 1:27:50
okay so now that we have this uh this that call method in our props you can safely say uh await props dot call method add candidate pair prompt prompt ref dot current dot value so promptref.current.value all that all that's going to do is return to us the value of the um of the string within the form within the within the form field um so if so in other words uh if we if you have a form it says if you've got a field that just says like candidate name it's just going to return to us the candidate name this in this sense is going to turn return to us the name of
- 1:28:48
the prompt that we're passing in so that's not too bad so um next one will be name one candidate name one uh dot current dot value right then name two copy we can actually say copy this line here paste it here and then turn that one to a two and for what uh then after that uh URL one we're gonna copy let's see this this line here candidate name one URL paste it here and take dot current
- 1:29:28
dot value and then URL two same thing dot current dot value and but change that one into a two if wondering hey Dory where'd you even get all these things from well remember we actually wrote that earlier in our smart contract so if we go back to our smart contract and go to add candid pair we can see prompt name one name two URL one URL two now um everything goes with it so we're just
- 1:29:51
adding uh this like prompt array of the names and URLs to the uh to the unordered map that we created earlier so go back to newpol.js and then underneath um just add candid pair uh function we're going to do another await and then do props Dot com method add to prompt array and then our arguments will be prompt prompt ref.current dot value all that all this function does if you recall it's just adding a prompt to that unordered set
- 1:30:39
that's all we're doing and then await props dot call method initialize votes initialize votes and then we're also going to add in the prompt as well here so we can actually just like copy this line this like object instance here um and then just replace it with the one we just wrote in here because it's the same argument um after that uh we conclude this function by saying change display message to True letting user know that
- 1:31:18
they can go back to the home page so now um so this is good this is good uh so we're going to go ahead and go ahead and design the actual like new polling page um so let's go ahead and go to the return statement add some parentheses and then establish a container with a style of margin top 10px there we go okay close that and then we could say we can start with a row and that row will have a card and the card will have a card body
- 1:32:07
and that card body we'll start off with the card.title and that title will save voting prompt so maybe it'll be good is actually if I combine these two pages we can see what we're doing so if I go here go to new poll uh we can see that we haven't defined URL ref let's just go ahead and do that so command B go back to newpole.js go up here to react and then just type in use ref use state
- 1:32:51
and put a comma in between the react of the braces like that so great we can see voting propped appear here so we're on the on the on the right path on the right path so it's pretty good um so underneath the voting prompt we're going to add what's called a form so type in form and then underneath the form we're going to have form dot group and give that form.group a class name of mb-3 hit save go inside the form.group
- 1:33:33
and then type in form dot label capital l prompt hit save and then we can see a little label appear there and then we can go below that we can say form dot control ref is equal to prompt ref placeholder is equal to add prompt so that must look like magic and what the heck is a form.control we'll perform dot control is if it ever shows up then that defined form I would import form oh we know we did oh I did from my bad sorry guys
- 1:34:29
there we go so you can see the add prompt appear here so this is the actual what Florida control is um so we're adding that field and that's our very first uh very first card so good job good job guys uh now let's keep going and add the cards for the candidates themselves so we could enter in the cad information um so below that row we're going to make a new row Row the class of the style of margin top margin top
- 1:35:01
5 VH and then after that we're going to close that tag to column class name equals equal to justify content Center D Flex so D Flex there we go it just centers everything for us uh close that tag and then after that enter in uh like another card so we're gonna have two columns here one column for one candidate and the other column for another candidate with the Style Style of with 18 REM close that card hit save
- 1:35:50
um inside that card we're gonna have a card body so the car battery we have a card dot title capital T candidate one information Canada one information uh let's see I just did that okay that's fine get rid of this make it easier see um and then after that we're gonna have a card dot sub title with a class name of mb-2 and text Dash muted and then we're going to and for that subtitle we're going to put enter your in information
- 1:36:50
for your first candidate hit save you can see that up here to the left here and then after that we're going to have another form dot group class name is equal to mb-3 uh if you're wondering where we're even getting these class names from it hopefully don't get you'll get too confused with those I'm just those are straightly straight from react bootstrap honestly like the the actual website and documentation
- 1:37:22
um they're just like corresponding to different types of stylings that reaction boot shops comes with uh but I'm just using the default ones for now so form label candidate one name uh inside this form group here uh so hopefully you caught that um and then uh as you can one name and then yeah underneath that we're gonna have another form dot control and this is essentially the last thing we're doing for uh this thing is that for the first
- 1:37:52
page it's not too bad right um hopefully the second card we just copy and paste all this information just turn all the ones into twos it's actually really easy so remember form control ref uh reference we created earlier candidate name one um that's where uh that Canada name wants to be able to pull these strings from the placeholder placeholder of enter candidate name and close that tag and there you go
- 1:38:23
um so that's candidate one name and their cat and the actual like place where we can actually retrieve that cat at one name uh we're still not quite done so we have to make a whole thing uh essentially you have to make a uh you have to make another another form group for the actual um URL as well so we can actually go ahead and copy this first form group so let's just copy this and paste it
- 1:38:46
down here hit save and just change some of the strings you put in already so I'm going to change this candidate one name to candid one change that name to image URL and change a reference to uh candidate name one URL and then for the placeholder just do enter candidate image URL and hit save and there you go so we have our first card and guess what we've done we've done the bulk of the work for the second card so we can we're so hopefully this
- 1:39:30
uh we don't have to go through all this again sounds really good so copy everything you see here uh inside and including the column tags copy that and paste it uh just below the first one so the the the closing tag of the first column after that change all the ones to twos so count it one information change it to two uh changes first to second change just count it one name to two change this reference to to a Cadet name
- 1:40:03
two changes can it one image URL to kind of two image URL and change this kind of named uh URL to two and hit save um so cool we just kind of Saved ourselves a bunch of time so if we expand that we can see our entire form that's really good uh we're almost done we're almost done guys I keep probably keep saying that but you know hopefully hopefully you believe me at some point um
- 1:40:30
so we're going to add another row and that's this row have a style of a margin top 10 10 VH what's happening with this Oh wrong row wrong row sorry but this is the closing tag of the of the of the above the top row there we go let's just copy all this put that style tag in our new row hit save inside of this new row we're going to make a button and that button will have a disabled VM
- 1:41:14
feature so disabled come on there we go is equal to disable button and then after that we have another property we're going to say on click send to blockchain foreign to blockchain and then variant is equal to primary and then we're going to close this off and say submit hit save and we're let's see then there's one last thing that's actually that's actually really it for um our form this is actually fully functioning form right now so we can actually enter in our information and submit it to the
- 1:42:03
blockchain I don't think that'll like be as much fun until we can actually see um see it so uh actually you know what we can get rid of this line and put in an alert here so in the center blockchain button or feature we're going to uh just add an alert and say return back to home screen that's gonna pop up after we uh send off our information so okay so now that we have uh a way to enter in our new polls we need to find a
- 1:42:49
way to read them into our home page right so let's go back to home.js all right so home.js and add some functions that allow us to retrieve and display that information so remember all this information is coming from this use state state variable so we need to find a way to update that use state state variable to then be able to display that information so within um so below your state variables we're going to use what's called a use effect and that's going to run a function each
- 1:43:20
time this component mounts right so we're going to make this function make an asynchronous function called get info and then call get info from within use effect reason why to make our own custom functions because we can't do something like this I wish we could that'd be a lot easier but you have to actually make uh an asynchronous function within use effect uh it's a really weird react thing but it's the only way to uh to do
- 1:43:43
this so we can say get info async uh let output equal to await props dot get prompts and then so you can see how that kind of comes in handy actually I don't I'm not sure if we actually made that so let's go back to home.js uh let's go back to app.js copy get prompts go down to our home element wherever that is right here and then go ahead and add that so we're going to add get prompts is equal to get prompts
- 1:44:24
cool so let's go back to our home.js page uh props that get prompts and we're going to say change prompt list to Output so now all that list of prompts is going to appear here um and update our prompt list and then we can say if output dot length equals to zero change disable button is set to true so that's going to disable our clear pulse button should there be nothing returned or should there be an empty
- 1:45:09
array return from get prompts after that um we have to actually activate this this get info button so we're going to hit like we're going to hit get info so we're going to call that with end use effect and then after our first callback function we're um let's see where is this going wrong okay we're gonna see what happened here saying that uh get all prompts is not found so let's just make sure I spelled everything correctly so it gets all prompts uh
- 1:46:00
there it is yep that's our problem so I put get all prompt except get all prompts so we can either fix that by adding an S and redeploying it or we just change the name of the front end but I like get all prompts better sounds a little more uh accurate so we're gonna do yarn deploy after we make this correction it's going to deploy that to um to our new Dev account and then once that's done we can
- 1:46:25
run yarn start and try this application again and let's make sure that this is uh spelled correctly in home.js as well or an app.js so get all prompts okay that's fine now we can so now our contracts update and deployed we can run yarn start and try this again so yarn start app is starting it's built uh it's still saying thing not found oh did it actually work this time okay great actually I think it works so if I do refresh oh nope
- 1:47:24
get all props okay so figure out I'll kind of figure out the issue um just to cover all my bases I delayed the near Dev folder which is only at the dev account reference and it also um uh deleted the uh parcel the dot partial cash folder just to make sure there weren't there wasn't any like weird front-end stuff I didn't know about but after that I ran yarn deploy again and then it created a new a new Dev account for me um and rebuilt my smart contract so now
- 1:47:55
uh now this is working so earlier I'm not entirely sure what was happening but um great so now we now have it working again I can even just like you know just for just for funsies I can uh save this to let's say let let output equal a weight and then console.log output and then also return output if hit save hit refresh we should see this empty array here which is exactly one so that's good so
- 1:48:34
now let's go back into home.js we have our get info button all sorted out and now we um we can go ahead and then just uh just like add a new prompt right so let's go ahead and add a new prompt to this so go to new poll and to close this down and we can say add new props we can say uh I don't know sun or moon right you can say sun here we don't need to add anything to the URL just yet we can say Moon here same thing
- 1:49:08
for this URL and then we can hit submit see if anything goes wrong so I didn't resign into this new Dev account so I have to actually approve this transaction um so that's okay um so let's go back to our home page I hit refresh okay let's actually try signing in first so log out sign in mind your wallet okay 27 hit connect um it's the reason why I have to resign in is because we have I have a new Dev account now so
- 1:49:45
um I have to give this new Dev account a new function call access key for this to work so now I can try again so new poll I can say uh sun or moon son Moon one two three some stuff hit submit wrong I submit button work okay return to home screen great we can see Center moon appear here so great we know that our uh we know that our submission button is working now I know something we forgot to do in our
- 1:50:25
new poll page I forgot to uh disable the home button so it should say change disable to true as soon as we hit the send to blockchain button now if we go back make a new poll say up or down you're up down some stuff some stuff hit submit that now this one's um is like disabled so we know it actually clicked it right no now I know it actually works it's actually doing something um so if I wait a little longer I can say return back to home screen
- 1:51:01
and then now you can see up or down appear here that's good um so now uh all that's left right all that's left um is to actually create our polling station so yeah let's go ahead and do that so very last page you have to create is our polling station page so go over to pullingstation.js inside of your front end folder and save components uh and then let's get rid of that um and here is actually where the user is going to be able to um well cast
- 1:51:34
their vote um so in order to in order to do this we're gonna need to do a few things first uh very you know per usual like a stat like uh get our Imports into our page so we can say import container row column button and by react we're going to get use state and use effect and before we even continue there's one um function that's kind of Fairly important to this polling station page so this polling station page will utilize the local storage to put to pull
- 1:52:18
in its information to then be able to display it on the screen so if I were to go to our app.js page and put Js we're going to um Define a new method here if we could find it here it is um it's called const change candidate function that's candidates function so multiple function async prompt um and what this does is that it'll take the uh the candidates names and the prompt names
- 1:53:05
um of our selected uh ever selected candidate pair and actually put them into local storage um so we can so then hopefully this will make sense uh and then within the polling station we're going to pull these names from local store should then be able to use them on it's on screen it's going to say let name pair equal to await View method get candidate pair prompt dot prompt I'm sorry prompt stupid prompt uh
- 1:53:45
the field prompt is going to be our value prompt or passing into this function that's all that's happening here so that fat we say await dot await local storage dot set item uh so we can actually go ahead and copy this line a few more times um and then first first we say candidate candidate one name pair zero copy this paste this here then churn count at one to candidate two and name parenting into name pair one and then after that uh set item for from
- 1:54:38
prompt and then prompt here so again local storage dot set item that's going to set the item named candid one with the value of name pair zero and if you remember what name pair is right or if you ever would get would get candid pair returns um is is that it's going to return this array of like you know candidate names candidate one candidate URL one then candidate to candidate
- 1:55:17
URL two oops uh sorry something happened okay there we go so um get candid pair actually I'm sorry no uh yeah so get candid pair I think that actually does something a little bit different um if I were to go to contract TS I'm gonna get candid pair uh actually what this does I'm sorry I messed up it's actually what this does it just Returns the the names of the two candidates we
- 1:55:51
have Canada Ray Canada Ray zero and two so that's just going to so all we're doing is taking these two candid names that's already being parched for us we don't actually have to like parse this entire array like I thought we did a minute ago we're just getting the two candidate names and putting them into local storage that's all it's happening same thing with prom so prompt Azure value other value uh prompt here so that's all that's happening here so we're gonna take that change candidate and function
- 1:56:16
and go down to polling station uh uh let's see right and then so we're gonna go down to um not polling station but we're actually going to go into the home to the home element so put this put this as change candidates inside of your home inside of your home uh component so now go back to home.js and then here where it says button right underneath by where it says button on um where it says go to poll we're going to
- 1:57:01
do on click and then we're going to say props dot change candidate element okay so this is going to pass in the name of the prompt and actually will be will probably be even clearer for you guys which I probably should have done earlier is changes elements to prompt name there we go just a little bit clearer what's happening so we're passing in uh uh uh there we go it's a props.change candidates so we're
- 1:57:50
passing in the prop name into the change candidates function which it will then uh retrieve the appropriate candidates from the cat get candidate pair function from our smart contract and return the names into the local storage and also Save The Prompt name into local source as well so then now with those in local storage we can go back to um the polling station let's go back to the pollingstation.js and then actually write our our component here to then be
- 1:58:21
able to retrieve those names from local storage and place them within the pollings booths so very first thing we do after we associate successfully uh imported our um a lot of imports uh we can now make our state variables so first state variable and the second state variable will just be temporary temporary images so const uh candy rail to take place of the images we load in uh from our user um uh so that the you know just until like the rate to a Raid 2 I'm actually like
- 1:58:53
display so either we're just loading images right so candidate uh one URL let's see candidate one URL got my candy dates actually change candidate one URL and that's gonna be equal to U state and then we're going to go over to just go over like icon finder iconfinder.com and search up like a free like loading image and just choose like the free ones and then hit that uh and you can just
- 1:59:41
like open this in a new tab take that value and place it place it in here so that's just going to be like our loading image until our actual images load in same thing for Canada too so change these to a two and then our next uh State variables will be const show results for when we're ready to show results so change results display that's going to be equal to a u state that's going to be equal to false or so that so that by default to false Next Step will be const button status
- 2:00:36
change button status you state false hit save the next state variable will be const candidate one votes change vote one it's equal to U state so this is going to be where we're updating the uh the uh vote count for each candidate so by default those can be zero and option D change that to two change that to a two after that last but not least const prompt change prompt that's going to be equal to use state
- 2:01:28
and that's going to be just two dashes for the empty prompt great Next Step uh we're gonna use the uh use effect to retrieve some information it's going to say use effect is equal to a callback function it's not equal to uh is a callback function inside the uh accepts the Callback function as an argument and then we're going to have our useful handy dandy get info asynchronous function so get info is equal to async
- 2:02:02
or say let X I'm actually gonna do that we're gonna first say um let prompt name is equal to local storage dot prompt then we can say uh let vote count so that's going to get the uh prompt name from local storage and I could say let vote count foreign props Dot View method get votes prompt prompt name there we go so that will retrieve our vote count for us should there be one but we're not going to display that to
- 2:02:56
the users just yet console.log vote count actually that was just for me so we can get rid of that um okay so the next step after that uh we need to actually go ahead and get the um get the images or get the URLs and then update the URL information uh in our state variables so we have the vote count set now let's go ahead and get the URLs so we can say await uh props Dot View method
- 2:03:37
get URL can't type there we go their arguments will be prompt localstorage dot get item prompt next up would be name and local storage dot get item candidate one so that's going to get the URL for candidate one we can always check the smart contract if you want if we need to remember if you need to remind you of what that uh this function actually does but it just gets the URL from candidate for the accountant one
- 2:04:26
and then we're gonna need the uh you know the exact same thing for a Canon 2 so let's just go ahead and copy this and change the ones to a two and there we go um Next Step will be change prompt it's going to say yeah change prompt local storage dot get item prompt that's going to update the prompt name in our in our um polling station so that's a more visual thing and after that we're going to get uh we're gonna check the user uh voted or not um did user vote why this is important is
- 2:05:15
because this will allow us to decide whether or not we want to display the results of the vote to the user uh local storage kit sorry get item we want to autopilot there for a minute um cool so did user uh did user vote first we're going to call this a method called did participate which accepts a prompt and the user's name to check if that user has ever voted in this particular poll before or not props.wallet dot account
- 2:06:02
ID then after that uh we're gonna take that did user vote value right and then put them into the state variables by saying oh wait uh by saying change results display dig use your vote that's going to return a Boolean and change button status did user vote great so did user vote where Turner Boolean which will modify both of these to either stay false or become true uh after that
- 2:06:43
um all we're gonna do is go to yep the end of views effect and have this monitor the show results uh field there we go um so then our next function we need to add for this is the ability to actually add a vote right so it's fairly important for a polling station so we can say const add vote as our function name which is an asynchronous function so we put async and then I'll accept a value of an index because we're going to choose whether or not we want the either
- 2:07:17
the first candidate to receive the vote or the second candidate to receive the vote vote so we're going to say change first thing we do is disable the button the voting buttons so change button status to true await props.com method add vote and then we're adding that vote to prompts localstorage dot get item it's right we're passing the prompt name to add the to the advert function from
- 2:07:49
our smart contract and then the indicee of the user that we want to vote for so index and that's really it uh Next Step will be you have to record the user so once we add the vote we have to say okay we've had the vote now the now to actually record the person who made the vote so props.com method record user and then we say prompt dot local storage dot get item prompt then after that we're going to say user that is going to be a props
- 2:08:38
dot wallet dot account ID hit save and then uh so now we've uh We've recorded the user for this particular prompt um and then we're going to uh get our updated vote count so we're gonna say let vote count equal await uh props Dot View method get votes and then our arguments will be just the prompt local storage dot get item prompt and after that we're gonna take that vote count which will turn two votes and say and update the uh vote count State variables
- 2:09:30
to change vote one vote count zero change vote two vote count one alert thanks for voting and then after that we're going to change this uh this results display change results display to true great so that's enough of like the back end magic right you're not really back end we don't mean like a background magic uh now to actually make our polling page let's go let's actually go to a poll we can go um to oh this doesn't actually work
- 2:10:19
uh okay maybe it doesn't work just yet let's see what's happening okay so that's just we have to go and update those but that's fine so actually yeah let's go and update let's go and update that button so that's pretty pretty important um so if we go to our home.js page home.js uh let's see what's happening so get pull go to pull check if this is actually responding so console vlog clicked
- 2:11:00
okay so we know this function is actually in called so something's wrong with the actual function let's go to props dot change candidate right so that's an app.js thing Cadets uh yep okay let's see what the issue is okay I forgot to uh do one thing so Props that change candidates uh we have to add this line here it says window dot location dot replace window dot location plus I'm sorry location.href
- 2:11:48
Plus polling pulling station there we go so now we should get redirected to the polling station if I click this button here great so we've been redirected to the polling station uh so now go back to pollingstation.js uh do a div I should say polling station make sure we're not crazy great so we see pulling station appear here so we know we're nowhere in the right place so let's go ahead and start filling this out so first thing I want you guys to uh
- 2:12:28
write will be a um a container so container inside this container we're gonna have a row inside that row we're going to have a column oh yeah it's fine inside that column I'm going to say that to make it more organized um we're going to first get that column a class name to Center everything you know it is it's going to be justify content Center and then D Dash Flex and we're also going to give a style so Style of with
- 2:13:15
20vw because it's a little more room there there we go um move down so then within this column we're going to create another row I'm sorry another container and within that exterior I have another row with the style of margin top five VH background color #c4 C4 C4 um and then we're going to close this row and within that row we're gonna have a div and that Dave will have a style of display
- 2:14:12
Flex justify content ER and padding of three VW and that's gonna be it for our div and within that Dave we're gonna call an image the image will have a style of display uh well same thing really no actually uh height sorry height of 35 35 VH and a width of 20 VW in that source and the image will belong to the candidate one URL the one that we retrieved earlier so that will just be our loading image
- 2:15:16
because you never actually loaded anything new into this page um but that's okay that's actually a good thing so we know we're on the right track um below the closing tab with the div and Below row I should say uh we're going to have uh you know conditional statement that will say show results question mark um so if we are to show results then we will say we're going to display uh essentially same thing so yeah class
- 2:15:51
name they don't have anywhere else has copy this uh so yeah save some time Style margin top 5 VH What's Happening Here hmm
- 2:16:55
quite strange actually let's see okay it's fine uh show results um great I was just missing closing tag for row that's fine um So within this row we're gonna have a div I have a style of uh display Flex copy justify content Center font size 8 VW padding 10 PX background color hashtag
- 2:18:02
C4 C4 C4 and then uh let's see closing div and then just put in candidate one votes and yeah otherwise no um so good job uh let's see one last thing is just the actual voting button so row the reason we haven't seen anything appear here is because like this uh this value is like set to like false right now so we're not displaying anything before to put an expiration Point here we should see this like zero appear here so that's all we recreated um we're just like we just created a way
- 2:18:59
to display the vote count which only gets displayed if the user has previously voted so next up is the actual voting button so same thing for the rows uh we can just yeah we just copy this thing here place that first row tag with that that other row tag um and then toss in a button disabled is equal to button status and then on click is equal to a callback function we're saying add vote
- 2:19:41
zero and vote so if we click this first button it's going to pass in the in the index 0 which is going to add a vote to that first candidate right so hopefully that makes sense um so that's really it for this First Column this next column is just a way to display the prompt tag and then the third column would just be another voting station for the second candidate so um we're gonna say first thing we'll do is going to say column right same thing as the first as the First Column so you can even grab that
- 2:20:21
First Column tag and just copy everything here and then replace this next one that just changed US 20 to a 10. and then within this column you're going to have another div right uh we can actually just copy this first div here too might be able to see what we can uh we can snag from this so we're gonna we're gonna place a div in here and keep Flex keep Center uh remove font size
- 2:20:57
um turn padding to to VW at a height of 20 pH and uh align items to be Center and text align also Center there we go and within this div we're just going to put in the prop name so we're just going to call prompt that's it so remember prompt here is just going to be like um we do put some margin here so say margin top uh 5V VH there we go that adds some spacing up there for us um so it's good so our prompt is right now just like these two like dashed lines
- 2:21:54
here which is like totally okay um because we don't we're not actually passed we don't actually have like a way to we don't actually have anything populating this right now so now we have one more column to fill and yep it's the other voting column so but the good news is uh the good news is is that we can just go to that first voting section we created copy everything uh within and
- 2:22:16
including the uh the uh column tags if I can uh navigate to it and paste it below this closing tag of the prompt column and then just like before we're going to change all these ones into a two so just go ahead and do that very very place okay so we're going to change candidate one URL to candid two URL uh we're gonna change candid one votes a candidate two votes and we're gonna change add vote to from zero to one and then I think that's really it foreign
- 2:23:00
yarn to start again so now if I go down to here okay this is looking pretty good and um actually if I were to change uh let's see if I were to go up to my state variable and change the show results to true we should see the shirt results appear here too so that's pretty awesome so directive files and now let's actually test this with a real the real prompt right um let's see and these actually these two weren't actually uh called yet so get info vote count oh it's because we so
- 2:23:47
notice uh reason with their calls because like this get info button is not actually being like called so after uh you define get info button the function I'm sorry get info function you actually have to call it so call it within it use uh yeah use effect on field and then you should also see this so let's see vote count get info uh line 41.
- 2:24:17
props.wallet dot account ID okay that's okay so what's happening here is we didn't pass in while it's a property so go to app.js go to polling station and just uh inside the list of attributes that we have here just I'm add one called wallet and let that equal wallet that's coming from that uh there you go that's coming from that imported like wallet uh right where is it yeah it's coming from here where uh the
- 2:24:48
attempt the create new app template automatically imported while for us that's pretty cool um okay so now let's actually add some real life you know some real some real images to this um let's see if what's happening here okay great um cat one prompt name okay two prompt name cancel uh let's see polling station and then change candid one URL okay actually yeah I kind of done move here um and then one more thing too around where we have these like to get URL
- 2:25:44
functions and we uh I want you to actually like wrap them with these change methods here so he's like he's like change uh functions from the state variables I'm just gonna put that right here and wrap it just like that and do the same thing for this next get URL function there we go so these broken links are actually good thing because we never actually put in images for up or down but let's go ahead and test that with a
- 2:26:21
real thing so let's go to new poll let's do dog or cat dog cat so we're having a half there we go um it's like an image of a dog let's choose this little pepper a little puppu open image a new tab copy oh look his little face paste here cat uh and let's choose let's choose this image of this little cat here kind of intense looking cat right copy paste we're gonna hit submit we're gonna wait a minute
- 2:27:22
Okay cool so now it's done so hit okay go back to the home page you can see dog or cat appear here you can hit go to poll you can see our pictures are a dog and cat appear right into our polling and our prompt as well so now we can cast our vote so I'm gonna cast my vote for this little puppy because I'm always gonna be a dog person foreign so hit OK and then I can see one appear
- 2:27:48
here so um there we go yeah we have a successful voting application great job guys you guys did it thank you guys so much for watching I hope you guys enjoyed this video please let me know what you guys want to see more of out of these tutorials uh let me know in the comments down below with that like subscribe and have a wonderful day thank you