MongoDB Cloud Atlas and Flutter Mini-Course

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Premiere starts in 40 minutes.

Posting this here as it incorporates serverside Dart. I'm aware of the rules forbidding posting too much Flutter stuff so to the moderators...let me know if you do not approve so I can remove. Thank you

๐Ÿ‘๏ธŽ︎ 7 ๐Ÿ‘ค๏ธŽ︎ u/jeropp ๐Ÿ“…๏ธŽ︎ Oct 05 2020 ๐Ÿ—ซ︎ replies

Sounds really interesting, do you have a repo or blog where I can read more about Mongo + Dart/Flutter, I find it easier to read the code first and watch the video for results later

๐Ÿ‘๏ธŽ︎ 1 ๐Ÿ‘ค๏ธŽ︎ u/HCG_Dartz ๐Ÿ“…๏ธŽ︎ Oct 05 2020 ๐Ÿ—ซ︎ replies
Captions
[Music] hello friends jamin here and welcome to this mini course we're going to be building a simple contacts list application using flutter and mongodb and what this app does is if we look at the demo that we've got here we have the mobile app and also we have the web version of it so this is all using the same code base the initial screen says no contacts listed so let's go ahead and add our first contact adding our first contact will generate a contact and then add it to a mongodb database we can also go ahead and add a couple more using the add button at the bottom right if there are too many for the current viewport then we are able to scroll through the contacts list in order to view this on the web version we can click this refresh icon and i will refresh the list here for the web in order to delete a contact we can click on this trash can icon as such and in order to see that update on the mobile we just click refresh to give us the update and if we go ahead and delete the rest of the contacts were back to this initial screen the reason why we're able to use the same code base for the web and the mobile is because the logic used to communicate with our mongodb database is written in a backend so there's a server that's running so we're going to be implementing that ups part of this mini course and also we're going to be setting up our database using the mongodb cloud service so mongodb atlas which will save the need for us to set up mongodb ourselves if this is your first time to the channel hit the subscribe button and the bell notification icon so you don't miss out on future tutorials demonstrating how to build full stack applications with dart and flutter and on that note let's get into it before we create our server we need to set up our mongodb cloud account and create a cluster there's no much to it you can click on try mongodb cloud and then you can set up an account i've already got an account so i'll go ahead and sign in and i'll log in with google and i'll just enter my details and when you're signed in you'll be made to create an organization because i already have an account i've created an organization already and i've created a project i'll go ahead and create a new project i'll call this one contacts list and i won't add any more members because i'm already set as a member over here so let's go ahead and create a project once you create a project you're asked to create a cluster and a cluster is essentially an environment that has got our mongodb database setup in there so i'll go ahead and build a cluster and just select other for preferred language and continue we'll create a free cluster and i'll leave the default options intact and i'll click create so this will therefore go ahead and create our cluster and set up mongodb with it a few moments later we can go ahead and connect to it which brings up this model we're gonna go ahead and restrict it to our current ip address so this is my one and i'll add that and then i'll create a user and then i'll create a password and once that's done i'll go ahead and create a database user i'll go on to the next step choosing a connection method so in fact we can test this out using the shell i'll click and copy that and i'll open the terminal and i'll paste our copied in here and we just need to change the database name and now go ahead and enter the password and we are now connected to our database so we can list the current databases that are there i'll do use test to create the test database and then let's go ahead and create a collection our collection will be called contacts okay let's add an entry to contacts so we'll do db.contacts.insert and we'll add our first contact name let me zoom out a little bit so we insert that okay let's list the contacts we just added so do db contacts.find and then here we have it so that's good i'll go ahead and exit it and then i'm gonna come to the code base i've got a client and server directory set up the client contains a flutter project setup and then the server contains a console based application in the pubspec.yaml we've added two packages so one is mongodart this allows us to connect to our mongodb database and this package allows us to set up a lightweight server and then under the lid directory we have a server. file created here with both packages imported in main.dart under the bin directory we've imported our alias server and then we've invoked the start function firstly we are going to log into our database we'll be connecting through our application so if we click on connect what we want is this connection string so i'll go ahead and copy that i'll create a variable called db and then we'll do db.create and this takes in that uri string that we copied our database name we'll call it test and let's close that off and then next we need to open the connection since we've already created our contacts collection let's also retrieve that and then our collection name which is contacts for now i'll go ahead and print out our collection and let's test this out right now our cd into server and before we run our main.dart we need to set our password okay let's run it and let's not forget to convert that to a list so i'll go ahead and run this again which gives us a list containing our first entry second thing we need to do is to create a server i'll store my port in a variable and then we'll create a server object so scbr and then now we can server.get so this will be a get request and our route will be the route and then the second argument is a list of callback functions and then each function gives us two objects the first object is a serve request and the second is a response object we will perform this operation so i'll cut that there we'll make our database call then we'll return a response we'll set the status code and then we'll invoke the json method so in here we'll pass in a map with a key called contacts and the value will be our collection next thing we need to do is to listen for connections on our server so we do serve.listen and we'll pass in the port you can also specify your callback which is a function and in here we just print server listening on port and then pass the port in here let's test this out all right we've got server listening and if i go ahead and make a request to our server we get this response let's go ahead and add another route which will be used to add an entry to our collection so we'll configure a method to handle a post request by invoking the post method on our server object we'll define our function i will invoke the save method on our collection and then to retrieve the payload we'll just do rec.body and then from here we'll return a json response and this json response will contain what was saved into our collection including the id we need to go ahead and find what we just added and then we'll pass in a special query so we want where the field name called name is equal to the name field in our request body let's test this out run that server again make a post request set the correct content type and then we'll pass in our payload to our endpoint so once that's added we get this response back from our collection so if we go ahead and make a get request then we now have two entries in our contacts list the last endpoint we need to is one for our delete request so removing an entry from our contacts will invoke the delete method and then this route will take in an id so we can specify a path variable by doing colon and then the name of the variable called id and then here we'll invoke the remove method on our collection and we'll have a query in here so where the id field name has this value so because the ids of type object id we can use the special object id class that we have here so we'll instantiate object id from hex string and then we can grab the id from our request params and then i'll close that off and once that's done we'll just return a 200 status code okay so let's try this out will cal make our delete request to locals8081 followed by our object id so let's delete our last entry as such and then we'll run it okay so that should have deleted it if i go ahead and make a get call now we just have one entry we are now in a good place to progress to our client i've gone ahead and opened the client directory in a new window i've added two packages to this flutter project so i've got deal which will enable us to talk to our server and then i've got faker which allows us to generate fake data so we'll be generating our contact names and i'll be coming to the main.darts file in here and this is just a basic boilerplate that's been generated i'll go ahead and get rid of all these comments let's run this up okay so now that we've got our basic up running i'll call it contact screen and i'll rename these as well let's hide the debug banner let's set the titles for these as well we'll center the title let's set the correct icon for this one so set it to take to add new contacts and then the icon will be person add okay that looks good also we need to add the refresh icon next to this one so i will wrap this floating action button in a row widget which means i'm able to duplicate this one and then here the tooltip will be refresh list which will use the refresh icon let's set the main axis alignment of our row to end and then between these two icons let's add a sized box which will introduce some spacing like so and then the background color for this will be set to purple alright so that was good the next thing we are going to do is to render the initial screen let's change this text to say no contacts listed we'll give it a style we'll set the font size to 20 so slightly bigger we'll get rid of this text widget and we will render a flat button the chart of this flat button will be a text widget i will say rgo first and let's give that a style as well and we don't need this extra parenthesis all right and the reason why we can't see that button even though it's right over here is because of the white text so let's make this purple we'll add some spacing between the text and the button and then we need to add an icon here we want the person outline in a bigger size and let's give it a a slightly lighter color all right that looks good to me to make this logic a bit more maintainable i'm going to move this bit into another widget so on the lib create folder called source and in here let's create a file called no contacts dot dot we'll create a stateless widget in here we'll return this bit so i'll cut all of that and then let's paste that in here like so i'm gonna go ahead and create another file called contact screen and i also import the no contacts.dart file which is because we are going to copy all of this in here and then in the body of our scaffold we'll render the no contact widget and i should call it no contacts with an s okay let's go ahead and import our contact screen and we should be good i'll go ahead and do a hot restart but everything should look good okay let's come back to our contact screen whenever we click add new contacts we want to go ahead and invoke a method called add contact we'll rename this method we'll get rid of this one we'll create a list of contacts we'll go ahead and add an entry to our contacts we'll just add a dummy contact like so for now let's just make this an empty function we'll come back to that later so then in our body in order to display these contacts we'll have a condition here so we'll say if the contacts list is empty show this no contacts message or else we want to render a list view the children of our list view will be our contacts and we're going to map over these and for each contact we will render a list tile widget which takes in a title and we just render a text widget containing the contact name so let's save that and let's go ahead and test this out so i'll click that i always forget to do this so whenever we map over that we need to convert it to a list like such okay so we've got some smith i'll go ahead and add we add another one and so on and so forth okay this list style also takes in a leading section we'll just have circle avatar which accepts a radius and then a child will just have these initials we need to also increase the font size we'll also add in a trailing widget so this will be a flat button the child will be an icon and this will be our delete icon okay we'll give that a bigger size and also we need to set an unpressed function for this flat button so that looks like that we also need some spacing between these list tiles so i'll wrap this list style in a padding widget and then the edge inserts will be symmetric because we want a padding on the vertical axis so i'll save that and i should space it out like that okay in order to allow us to be able to reach the delete button on the last entry i'll go ahead and so we'll spread these contacts in another list like so which means that we can add a new entry with a height of 70. so now we are able to scroll the last entry upwards a bit to allow us to click on that i'll go back to our no contacts widget and let's implement this bit so on pressed when we click this button we want to go ahead and add our first entry and to do that let's expose a function called on add i'll define my constructor and then we'll do this dot on add so that when we click on this button we'll invoke the on add function that we pass in so in our contact screen over here we can do an add and then we invoke add contact okay so so that if i go ahead and click audio first it adds our contact before we look at connecting to our api i'm going to move this bit into another widget just to help us manage this a bit better and uh lip source i'll create a new file we'll call it contacts listing dot dot we'll create another stateless widget and in here we'll return all of that so i'll cut this from here and then i'll paste this here like so let's import our no contacts widget and then let's define parameters so i'll define a list of contacts and then we'll have our own add function which just returns void i'll define my constructor which takes in a list of contacts and then the on add function so which means here we just do on add and back to contact screen we will import our contacts listing and let's just render that here let's pass in our contacts and our on add function let's test this out i do a hot restart and if i click that it adds it also when we click that it adds another entry okay that's good before we delete let's go ahead and use the faker package i'll import that and then in add contact i'll create a faker object and then we want a an auto generated person and in that person object we want the person's first name and then the person's last name so we're now able to pass this in here like such so if i go ahead and click this now we're able to get randomly generated names like so let's go ahead and work on the delete functionality so on each of these list tiles when we click on delete we'll also go ahead and invoke on on delete function which will contain the contact name and then we can define that here so this will be a function that takes in a string and i'll just call it id it'll make sense later i will say on delete and then right after here we'll do undelete so this means for us we can come back to our contact screen and then we'll define our on delete named argument and then we'll invoke a delete contacts function so let's go ahead and create that now so right here we'll trigger a set state and then we'll just want to do contacts dot remove where and for each contact you want to remove where the contact name matches the id and i was meant to call it delete contact okay so let's test this out if i click delete here it should delete both of them so we can go ahead and now we are able to delete so if i add more and i delete it okay so this puts us in a good place to start talking to our api so our server is still running i'll go ahead and create another file in here called api dot dot i'll import the deal package and then i'll create a class called contacts api i'll instantiate deal and then i'll configure the base options particularly we want to configure the base url which is localhost 8081 with a trailing slash and then let's define the methods to retrieve all our contacts so this will return a list and in here let's make our call i'll create a variable called response and then i'll make the get call and then we'll return our response.data so if we remember our response.data contains a key called contacts which is our list in fact let's check the browser so it looks like that so we just need to access this which gives us the list containing the id and the name okay so let's check this out i'll save this and then back to our contact screen i'll import api.dot we will need to make our api call when the app first loads so i'll create a state property called loading and i'll set it to true initially and then we need to override the interstate method to use our api we'll create an instance of our api here so we'll do that and then we'll instantiate our contacts api this allows us therefore to make our api call in here by doing widget.api.getcontacts once we have our contacts we can do a state update and then we'll set our contacts to the data that came back and then we'll set loading to false which brings us back to our build function we'll have a condition to check if it's loading then we want to render a center widget with a circular progress indicator or else we'll just go ahead and render this widget so now doing that gives us that okay so let me do a hot restart all right so dina hot restart gives us that which is from our database also one thing worth mentioning i did this earlier on because this code is running on the emulator accessing localhost 8081 attempts to access this directly on the emulator rather than this host machine that the emulator is running on so in order to access localhost on this machine from the emulator you need to go into your terminal and run adb reverse and what you want to do is to do tcp colon port 8081 so this is the port on the emulator and you want to forward it to tcp port 8081 on this host machine so if you run that then that means you're able to access this host machine from the emulator so now we successfully managed to get our contacts from the database next i want to create a data object which will wrap each of our contacts because currently we are accessing it like such which really isn't that pretty and also in that dart object we are able to generate these initials as well i'll create a new file our collet contact this will consist of a class called contact it'll have two properties id and name i'll make these type string i'll create a named constructor but this will be a private one which will set the id and then the name so the reason for this private one is because we are going to create a factory constructor called contact from json because the response that comes back is a json object so we'll take each json object and then we are going to return our private named constructor so in here we just want to pass in the the id from our json and then the name also doing this now allows us to have a helper to or to generate our initials based on the name so i'll do that by creating a getter called initials and in here i'll create a variable called names which will take in the name and then we'll just split it into an array so split it based on the space between them and then we just want to return names 0 and then we do substring 0 1 so we are extracting the very first letter from the first name so which will be j we'll do the same for the last one let's try this quickly so we'll come here to our contacts api we'll import contact dot dot and then rather than future being of type list we want it to be a list containing contact objects and then in our return we'll cast this to a list so that we're able to invoke the map and then for each item in the list we'll create a contact from jason and in fact let's just call this json like such and then not forgetting to convert it to a list so now we'll come back to our contacts screen and then we'll also import contact here this will be a list of type contacts and then this bit will simply be contacts from jason and this bit we want to remove where contact that name is equal to that okay it's broken but we'll fix it shortly let's go in our contacts listing and then here we also import contact dot dot and we'll set the right type here like such which means for our contacts list over here we can do contact initials contact.name and then for the on delete the contact id which reminds me i need to correct that here as well so do contact the id all right let's go ahead and hot restart and test this out and let's add a couple more entries okay let's delete all right it deletes all of them okay richard is happening because when we add a contact we're not adding an id so let's go back to our contact object from the json response the id has got this bit and when we are making our delete call we we need to send this string so we're going to write some logic to remove those and in here i'll create an id variable and then we'll do json id dot replace all i'll copy this bit just so i don't type it wrong so we'll replace that in an empty string and then we want to replace this bit with an empty string then we'll pass in the id here and in fact rather than making this a getter i'll just create a field called initials and then i'll move this over here and i'll create a final variable called initials over here will be the name field from our json like so and also rather than repeating this name twice so let's create name here and we'll store this here then we can do name and then name and then we'll pass in our initials here which means we do this.initials and we'll get rid of that and i think i can make this a const constructor then let me hot restart all right i made a mistake should be replace oh let me hot restart again so i'll come back to our api and then let's define another method which will create a contact in our database i'll create a variable called response which will contain the result of our post also this method will take in a name that we need to add and in our diopost method takes in a payload so this will be a map object with a field called name and then the value is our name that's been passed in will return this new entry like such so from here we'll come back to our contacts screen then under add contact we'll make our api call passing in the full name here so then afterwards we can go ahead and add the results to our contacts list like so and then this bit remains the same because once our contact is retrieved it will contain the id okay so let's try this out okay so we got that working and when i hit delete perfect we are able to delete as well and everything should pretty much work the same so no contacts listed i click it adds my first and so on and so forth all right that's good i believe at this point we should be able to check that this also runs on the web so let me run the web version of this and what i'll do is i'll build this as a web project we'll do flutter build web virtual compile our flatter app for the web and it will place all of it within this build directory that is just created so it's still running okay so it's done now and under build we've got the web directory with with our flutter app let's cd into web and then let's serve that directory so it's running now on port 8080 and then when i launch it we are getting a cause issue calls this as an acronym it stands for cross-origin resource sharing and it's a mechanism that uses http headers such as this one to inform the browser that our web app running in this url should be able to access the resources at this url so when the call is made chrome goes ahead and makes a request to locals8081 which is our server a response gets sent back the responses that doesn't contain the setting and because of that chrome does not go ahead and complete a full request so to resolve this we need to go back to our server and add a couple of headers which will allow chrome to go ahead and make the full request so i'll put this to the side let's open our server again in our server i'll create a function this function will have the same signature as this one here we want to reset a couple of response edits and then we want to add a header called access control allow origin we can set it to locals 8080 but i'll just put asterisk which will allow any origin once we've set this we can we need to pass this in for each of our endpoints so for our delete also for our post and for our get we also need to create an options route because chrome initially makes a request using the options verb to the route we are trying to access which will return this header and then once it's successful chrome will go ahead and make the actual request to the particular endpoints we are trying to access so we do that and then for our callbacks once we set our response headers we need to actually end the response like so so let's test this out by running the server again and let's reload so now we have this we can add okay we can't add a contact this is the same course policy in this case we also need to add in another header so access control allow headers so we'll come back to the server and let's go ahead and add our second header with this one we'll specify the headers we'll allow to be sent across to our server so we'll allow the origin header and we'll allow the content type header we need to add a third header called access control allow methods and then we'll specify the methods that are allowed so we have get we have post and then we have delete and let's run the server again okay i'll pull back the browser and i'll reload i'll go ahead and add okay we are able to add new entries okay that's good let's return to our api and implement the delete behavior this will take in our id we'll make our call to delete then we'll pass the id in and we'll just return the response from that we'll come to our contacts and then over here we'll make our call to delete our contact let's mark this as a sync and then we'll update our list of contacts here as such so if i delete that that should also delete it in our database and let's check this in the browser i'll go ahead and build for web again and let me kill this server and then run it again okay let's delete an entry all right so we made a call to our endpoint and we get 200 okay and we can delete as many of these as possible okay if for some reason you're getting an issue and trying to delete just amend this options endpoint and add an entry for this route i can do that here like so i'll create a variable called course puffs containing each of these routes and then i'll have a loop or var routing calls paths and i'll just repeat this for both so in here we'll have the particular route and then i can run the server again you may not have to do this approach but if for some reason you're having problems with the delete then do this bit as well i'll bring this back up and then i'll delete that and then let's go ahead and add our first entry and so on and so forth and you can delete that so that looks good the last functionality we need to implement is the refresh because at the moment when we click it nothing happens i will create a method called load contacts and i'll move this over here like so when we are loading contacts we need to set loading to true again so to allow us to reuse this for when we initially load our state and later on when we invoke loading contacts i am going to add a an optional parameter here of type bool i'll call it show spinner by default it will be set to false so that initially when we are running this load contacts our show spin are set to false because loading will already be set to true when this view is loaded initially however later on when we set this to true we'll have a check in here and then to respond to that we'll invoke set state setting loading to true like so and let's wrap this like that so it's much more legible okay so now we need to go down to our build function and in here we will invoke load contacts and then we should set our spinner to true there should be exactly one entry in the database so if i click refresh here then it's now updated and then let me build this web version again okay once that's done i'll reload this let's add a couple of entries here and then i should be able to refresh the list let me close this server and run it again so let's try this again so delete on entry and when i hit refresh yeah it goes ahead and deletes it let's delete a couple more when i refresh easily to that when i add some more here and i refresh the mobile view it gets the update and when i clear everything and refresh that also brings me here so from here you are now able to deploy this app in particular the website and the server to a service like heroku if you want to take up that challenge i've got a video demonstrating how you can deploy your dart app to heroku so check that out and that being said i'm going to end the video here if you enjoyed it smash that like button if you are not a subscriber hit the subscribe button and the bell notification icon so you don't miss out on future tutorials demonstrating how to build full stack applications with dart and flutter if you've got any questions let me know down below and i'll see you in the next one thank you
Info
Channel: Creative Bracket โ€ข Dart and Flutter Tutorials
Views: 18,140
Rating: undefined out of 5
Keywords: dartlang, dart tutorial, fullstack dart, flutter mongodb, dart mongodb, mongodb cloud, mongodb tutorial
Id: juKDXPk7kU4
Channel Id: undefined
Length: 37min 43sec (2263 seconds)
Published: Mon Oct 05 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.