We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
Daniel Amber · 5.2K views · 209 likes
Analysis Summary
Worth Noting
Positive elements
- This video provides a high-quality, hands-on look at ClojureScript/Node.js interoperability, specifically explaining how to handle ES6 module defaults and promise-based workflows in a functional context.
Influence Dimensions
How are these scored?About this analysis
Knowing about these techniques makes them visible, not powerless. The ones that work best on you are the ones that match beliefs you already hold.
This analysis is a tool for your own thinking — what you do with it is up to you.
Related content covering similar topics.
Transcript
hey what's up guys today i want to do a video on nbb that's uh babashka scripting with node created by michael and i'm here with michael what's up michael hey daniel what's up what's up thanks for joining me on this video yeah so today we're going to create a way to manage birthdays using a simple node script written with mbb seems like a good idea yeah cool let's get started first off i think we need to install mbb so if you don't have mvb installed it's dead simple just go to the basket github page and then there's an mbb install script yeah it's just with installed with npm and then let's just run that and it'll install mbb for us so how does it work does it actually convert closure to javascript no it executes close your script on the fly using an interpreter so it doesn't emit any javascript code it just runs in javascript already and is ready to execute close your script directly using an interpreter okay so we've installed it so now we can run mbb and i think we could run closure in here yep yeah that works so let's make a project so i'm going to make it actually i'm going to call it birth manager let's see the n2 birth man and open it in vs code okay so what should the first step be just create an app.cljs file or yeah yeah let's do that cool and the cool thing with mbb is we can actually use node packages so [Music] uh people who write javascript love packages so we can install quite a few now so for a birthday manager so this is going to be a command line utility yeah yeah so first first maybe we should uh create a package.json i think okay so we can go npm init and if you a bit lazy you can put dash wide oh version one already cool that's our project so yeah so once we've created the package.json we can actually install some node packages so i already have some open here so we obviously need nvb then we can use enquirer inquire is a nice utility which allows us to ask questions at the command line and answer them so here you can prompt the user to answer something and it allows you to interface here you can give choices and give some formatting it's really cool so let's include this npm install inquire just copy and then we can also install i thought because a lot of node developers like mongodb we should use mongodb and you can because of the closure script interrupt which we'll cover a lot of in this video so we'll install and set up a mongodb so first let's store mongodb and then the last thing is because we're dealing with dates you can't deal with dates without using moment so let's use moments and just install those cool so let's get started on our project yeah so maybe we can open the n-rebel for mbb and since you're in calva calva already has a way to do this ctrl shift p i think for the yes and then kalva start a project repo i think yeah yeah then and nbb yeah can i choose mbd cool yeah yeah yeah and you can ignore the error messages in the bottom so there are there's a few things that nrepo server of nbb doesn't support but that's not a problem for it's it just logs those so so maybe for the viewers who don't know what an nrapple server is nrappleserver is a way to have a process that listens to messages from your editor which supports a repo driven workflow an nrapple server can run runs in your process yeah just offers a way to to have nice integration with your editor like evaluation of expressions but also completions for example maybe we can try uh some expressions and evaluate them in this file against the nrepo that we now have yeah so now we started a ripple and we can evaluate code inside of here so if we go to plus one one so add we can evaluate it's two and get the results straight away so maybe we can require moment.js just to try if we can get that working in here yeah so the first thing we'll do is just make a namespace and should we just call this app yeah this name says app dot apply and we can require okay so we want to require a moment yeah so so packaged yeah so in nbb you have to use a string for every javascript package that you're going to require and then it's the same name that you use in node when you say import and then a string cool so yeah here we go oh yeah so yeah so but but nbb is based on ecmascript six it supports uh it sees all the libraries as ecmascript six so you should look at what's below in r in es6 syntax there it says import moment from moment so let's try that so you let's just use the moment string and see what happens and then we type okay and then we do as moment yep and then evaluate it okay so now we define this namespace and if you now type moment and then slash so you see this thing called default oh yes so uh this means that there is a default export in the ecmascript 6 module so we actually have to import that default export so ecmascript 6 modules can export named things like export foo export bar but they can also do export default and then it's the default function nbb sees every ecmascript model does just as an object so you have to get this default export out of it and that's where we have the dollar sign notation for so if you go to moment and then dollar and then default and then evaluate this again yeah and now we can actually use moments yeah yes yeah yeah so just uh just to clarify on that so you're saying um if you're familiar with writing a node you would do something like export module dot default yeah and then you would have a function here like through there so quickly and then that would be a function and then what you're doing is we are getting this object back right exactly so we can we can uh do we see we can see this in node uh as well so if you go into your terminal and uh and then open a node rapple if you open another another terminal if that's possible cool yeah so uh if you do note okay and if you now do uh await and then import and then open pairing and then the string moment so this is a dynamic import uh and normally this returns a promise but with a weight we get the result from the promise so if you press enter you see actually if you scroll a bit that there is a default uh field there so that's that's the thing that we're now getting in nbb cool so we're getting all of these available awesome okay that's good to know so okay so now we're required moment should we actually just require all the libraries as we will need them yeah or we can maybe try one example for a moment to see if it actually works yeah okay so i mean if you run the moment normally should so we're going to use java enter the javascript interrupt so if you go i think you go moment dot yeah something like this you should get the i think that's the syntax there this will create a new moment so this is basically a running moment without any arguments and then we want to run dot euro on there and we should get there 202 cool okay great it works it works cool so the way we should probably start this is well let's actually look at running how we would also run this because we're going to run around this file so let's just execute frontline hey and let's run this transcript with mbb we just have to run nbb and i think the name of the file after that that's it and it's executed cool that's that's simple enough let's import inquirer because this is how we first going to start with our questions how you said so we need to import it let me just make sure i split properly by copying it sometimes it works with without default and sometimes it works with default but this depends on how they export things so yeah so you could actually use it the same way without default well sometimes it depends if the package tries to be both things at the same time an ex ecmascript or a common js thing so it's a bit weird because this node.js ecosystem is a little bit in transition from common js to ecmascript i think because ecmascript is now kind of the default module format but not everybody is used to this so what they sometimes do is both export a default function but also put everything on the top level so you get everything everything everywhere yeah yeah okay so basically what we're going to do is ask you for a name a day and a month and every time it's that day of the month you should get a notification that's this person's birthday let's see that's the fine we're going to ask questions so let's see how the inquiry practice works first oh yeah cool so we need a question object let's see okay so it can take a type a name a message so we'll create an object here and we'll get a type of input because that's what we want the message would be whose birthday is it and we're going to have a default value yeah okay and we need to give it a name and the name would be the variable value that gets returned so the name would be name and what's input here input is supposed to be a string okay cool so let's see how we can actually use this so that's the question object okay so you run inquiry.prompt and then you'll get so you get a promise back so if we go back here so we have this should be quest so this will be an array of questions at some point so let's just make this a vector cool so let's ask this so we want to use inquirer and let's go back here it has this prompt function okay so prompt and it needs prompts so this array of prompts which i think is just questions probably need to convert it to javascript right yeah so there's a couple of ways we could do that um i've seen you can do it with uh pound sign js yeah but that's only one level so if you if you want to do it like this you have to also put another js before the map oh like that like so yeah okay that works yeah so that's so this only works so one level so now this would be seen as a javascript object and this is a javascript array right but you can get around that by using the cljs to js function here so let's wrap this with cljs and we want to convert it to js yep well it's clj to js actually so so the the the things that you're seeing is coming from sales condo which says well this function i don't know so if you correct that then the curlies go away so cljs condo is this plugin here you can download made by michael and it will link your it'll link your code which is awesome let's see what happens if we run this yeah we can try it from the rebel maybe i don't know what happens if you run inquire from from the rebel actually i don't think it actually works yeah evaluate anything yeah evaluate this evaluate our questions and then let's see what happens oh we get a promise back that's good okay so i saw that uh ndd has like an awesome way of dealing with promises using uh premier from the server yeah yeah yeah uh from mesa it's called uh so if you go to the requires and then put promesa.cor without a string because it's a closed script namespace and then as promesa or sp i usually do sp yeah and then you can do p let for example to bind uh yeah p let it works like the normal closure that but it's for promises so if you uh do peel that and then x for example and then the enquirer prompt then the result from this inquire prompt is bound to x and we could we could print x and let's see what what uh what it is so why is it saying it's not so that you can solve this maybe it's nice to explain that sales your condo doesn't know about this promesa let macro by default but you can tell say the condo to to lend this or treat this exactly as to close your core let's how we can do that is go to your project root and then create a directory called salesjohn.condo okay got one here yeah and then create a file in there called config.eden okay and then open a map with a key called linds yep and then a new map and then uh you we type promesa.cor slash let and then close your corelets so this is saying to treat uh that delete that comes from this namespace the same way we would treat it as this one exactly and now the error should be gone in your buffer if you type again because yeah it needs to refresh okay cool yeah that was easy uh cool so now if we run this whose birthday is it it's my birthday and then we get a name back cool so this is really awesome um i just want to so this would be the equivalent of javascript you say x something like const x is equal to a weight and the result from this promise exactly so cool okay so we we can actually call this answers is that what we're getting and now we're really getting the name so how would we get that name from answers so if we go back let's just go back to the terminal we see we're getting it back as a javascript object yeah so we'd have to convert this to closure yeah what we can do there is make another binding called answer or name let's say or yeah and then you can do interrupt so uh open a parent and then do a dots followed by a hyphen and this is the syntax for a field so if you put a write name now and then answers that's the syntax for getting the name out of the answers and then we could try to print that let's do that yep cool we have the name out so we need to get the name we need to get the month let's try and so we'll add a another question here and we'll call it so we get the day first of the month let's get the day okay look at the day and the type so this type actually has to be a number let's see if there's a type for a number maybe integer or javascript doesn't really have integers right [Laughter] magic i don't know how i like i think inquirer i saw because we have the input type so i'm just wondering if there's also a number type yeah so there's a number type okay so i think if we don't put a number in then it won't allow us to continue so let's go a number and message what day is their birthday and so if we now run this let's just clear this up here's dan right there's a birthday 14 so that works i think but i think there's an issue with that so if we get the let's just also get the day out because and we'll get from here so now this would be day but we can also by the way what we can also do maybe that's nicer is convert answers first back to a closurescript object and then we could use uh destructuring okay cool so i'm assuming to convert back to do to exactly just the closure is the opposite of this so let's do it so we can go yeah but you cannot do you cannot do this directly unfortunately because you have to first bind it to a name because then promesa binds it the the promised result so here we have a promise this will return us a promise and okay so if we want to convert answers so we could do something like answers and then answers here we can go um javascript to closure with answers and then it's an arrow actually uh so jss yeah let's let's just print answers first let's uh okay let's make sure we know what we have cool and let's go back here and i'll also show i'll show you what's funky about this also so we can go dan and what day is their birthday we can say something like 400. we could kiwa die it could be keyword eyes yeah yeah so yeah she put as the last argument in this function keyword dies keys i think is the key word keyword true i think that's yeah i think that's it let's see what we get let's give you a birthday that's right yeah let's say hey cool awesome okay yeah so that's that now we don't have to use the javascript interrupt to get the name from the object to get the data from object we could actually go here you can say keys and we can get out the name and the day yep oh yeah and remove the interrupt from yeah yeah and oh yeah maybe a nice to know if you don't use print line but prn then you actually get to see the strings as they are instead of uh yeah else you cannot really see if it's a symbol or a string oh that's amazing okay so now we have a string value here we have an integer value there let's try and uh just fix this so that a number can only be between 1 and 31 and that's yeah inquiry allows us to do that really easily there's this you can pass through validate and it takes in a function and it receives the value and if you return false then the value is not accepted so what we can do is yeah it's like this is super cool so validate and we need to pass through a function here so let's create an anonymous function and that will take in a value and what we could do is we could check if the value is this one the value is between 1 and 31. and now if we run this yeah we can that's a really nice way of writing it enclosure say peter and what they let's say 900 doesn't work ah okay it doesn't accept the input it doesn't accept it kind of broke there but i don't know why so let's say um i don't know what name starts with g g and then four and that will work oh nice and does it also accept a function of the previous answers because then we could do more advanced validation a function of the previous answers so you could actually validate if the day of the month is valid uh if you first ask for the for the month yeah so i don't i don't know if it accepts that but maybe that goes too far for this but i mean even then that is pretty cool what you could do is you could just have a variable set somewhere else and you can set the month first and then you'd have access to the month within it oh yeah yeah of course yeah cool but now we have that let's get the let's get the months now so for the months we can use a string so let's uh so we'll call this month type the b i think type is list so i basically want the user to go through a list of the months so just pressing enter yeah yeah it'll be pretty cool choice choices maybe right right choices no choices is the would be the list of the months yeah and then we've yeah and they'll choose the type would be this all right yeah yeah so type would be list and then so just to show yeah so like if we had choices and we had like hey and we ran this choice choices plural maybe oh yeah i think you're right okay cool so there we go okay cool cool ah okay so now let's try and see if we can get the list so let's say d one oh this is actually isn't working oh d1 doesn't work because this must be greater than or equal oh okay yeah and now we have a list though that we could choose without cool that's that's pretty yeah it's nice so and then also so now with moment we can actually get a list of all the months yeah okay so we can run moment dot months okay so okay so the for some reason the autocomplete's not working but we should be able to do this i mean i don't know this is the same as calling months on moment but can you evaluate this okay yeah it's a function this is a function okay yeah so okay so you can call it like that nice and we get the months and yeah so that's javascript but i don't think but does actually matter if it returns javascript in here no it's fine so now what we can do is we can run this again a month that's awesome cool and it rolls through them it actually looks quite nice dude cool okay so let's just get the month out of our answers and we can just spend months for now can also actually we can use this in our script we could say saving birthday for yeah now we we have the data what do we do yeah save it yeah we need a favorite i want to set up a mongodb instance i hope it actually doesn't take that long i forgot how long it takes okay uh we'll be right back after the break okay cool so i've created i've logged into mongodb and i have a cluster running i'm just going to add a new database so to do that add my own data add database name let's call it birthdays db and collection name we'll call it birthdays create cool we can actually start using this um for to you need to get you use your api key to actually write data to here okay cool so i'll go to database access and here okay we have a user already i don't know if i created this user but we'll add a new user to our database and it will use a password so i'll generate a password here let's call the password secret i would never let me do this okay um oh is this a username a user okay call this on the code again okay i already have one called on the code again let's call this mbb cool yeah the password is secret and read and write to any database that's perfect temporary user yeah so if you guys want a free database just use these credentials [Laughter] i'd use it nice the process is too easy oh it's too weak let's try secret with exclamation mark and let's say one two three no one will guess that okay no no it's super yeah so let's play those just put those details here let's define a password um as secret one two three and we'll define the user as ndv let's see if we can actually just connect to so long yeah so we can include that's mango db by default and i think we can even we still have the rebel running yeah did we already install mongodb as a dependency yeah we did yeah we did so here's mongodb okay yeah closer we should be able to evaluate this cool thing and now we'll have access to db right so there's like a billion ways to learn how to insert data into mongodb connector database using node that's exactly what we want cool so we've installed mongodb we've required it okay yeah yeah yeah okay so we need to get our client client okay so here's the uri so let's just copy this okay we'll just set of cons we'll go to define uri and then we'll grab this so we need to have this as a string and the reason for that is so we can replace our username here yeah user and we can replace our password here your cluster url let's see if we can get that all right come online tools and connect okay can i because it's just going here yes okay okay cool so here we go and we have our cluster url should we just copy this yeah we need a javascript to close the script converter i mean [Music] that's what you are oh okay okay uh cool so this is copy the end of this part right and we can replace this here it looks like we put the database name in this string and i think this is the default database so we called it like birthday [Music] okay oh i can try it from the ripple yeah we can evaluate this evaluate this and we can evaluate this so now we have our uri which should be right yep yeah mvb with this secret password and so let's try and write something to here to this database okay let's now we need to get to that second part i think mongodb slash and then client right so mango b with capital letters i think yeah okay like this so i think it was with capital letters so if you oh yes this is like instantiating a new one yeah okay cool null and object are a little bit different so i think yeah we can just pass in the uri yeah oh yeah you have to place a dot because this is a constructor or or put new before yeah so you can i put a dot here yeah yeah that that's that's how you invoke a constructor in enclose your script so this should be the same as mongodb yeah or or you can do uh put instead of the dot you can put new before the mongodb yeah that also works and then remove the dot that's the same syntax but just different uh same same but different yeah yeah synthetic sugar actually the dot is synthetic sugar for the new yeah okay so you can do what you want whichever you prefer there right so i think this returns let's return the client straight away okay so we we can see it in the report what it returns so yeah so now if excuse us oh yeah it returns us yeah we can do dev client or something and we can move this in cool so now we have our client let's look at how we can insert beta into uh database cool so this was connections yep connect ah now we call connect and that returns a promise uh okay so let's do that press the connection so yeah so let's do that with promesa so then we just make a function here and we'll call it right data and we can start doing everything in here yeah that's nice yeah with premise so we can go p-lit and we'll get a connection back from our client yeah but we have to run the connect function on here yeah connect yep and there is actually a nice way in nba to inspect what comes back back from uh promise in the rebel okay so you don't have to uh execute the script from the command line all the time and see what it prints so what you can do there it's only intended for rebel usage but what you can do is require nbb.cor and then refer await i think and then what we can do is uh well return con from this function con would be the awaited connection yeah and then evaluate this function and oh yeah you haven't evaluated client yet yeah so now we have our client and we can go here so if now we can open a comment form right so what we can do now is write a weight and then call the write data function and then evaluate that so i'll wait like this yeah with write data yeah call the function as with as a function obviously yeah yeah yeah yeah okay so now we'll get our connection back yep should be yeah okay that's cool we got an object back yeah so now we can test this function every step that we add to the function we can test in this comment block let's search for insert data mongodb node.js exactly oh yeah okay cool okay this is perfect so we need to get okay so we've done the connection we have our connection and so i know i know with the mongodb is that you can if you don't uh pass a call back it actually returns it yeah but i think if you call it without a callback then it will return a promise that that's what a lot of these uh javascript libraries do right yeah i think so so we can get so if we run here we go and climb.connect and then on the db they're connecting to a db so okay so i'm not gonna we can say connection.db i think connection dot db and then we need to pass through the database name and that was birthday db and then okay and then we can call on that maybe we can get the collection so we can call this collection and get dot collection so it's this dark collection without dbo um the collection is birthdays okay and let's just see if that's right so i'll just return here and then do this trick cool we get a nice object back we should be able to run this insert one on this collection so what does that return an error response so we can go yeah i think it returns a promise again yeah that's a callback i expect insert one on the collection and let's just say so this is just a map [Laughter] and uh this i think you have to convert this to javascript so we can do that js so this can be a javascript object like that and let's see what the response is um so if we evaluate this and then this i thought it's true with an insert id cool so it's pretty pretty fast right yeah i expected that to take like two nights [Laughter] of just being just writing it the collection like uh writing it is pretty quick so the servers are right they're very close to me ah there it is fubu nice okay so now we can write data so maybe we should make this right birthday or something yep i think it makes more sense right birthday and it'll take in the name the day and the month and here we can say just make this name and that'll be the name the day will be the day and the month and now we cannot write birthday [Music] so i think also because we're dealing with strings and we're going to have to look up the birthday later on we should probably convert this 18 to a string because i think mongodb does have types so let's do a string here and convert data string and i think it's sure this is nearly there if we run this oh wow that was really fast that was fast um it's in the same city or no it's not the same city but it's it's close cool we have the data there that's nice um so now it's saving we can write we can run that function here we can go uh write birthday name day month cool so now let's try and test this from the command line so here we go whose birthday is it let's say it's yours eight eight february cool we should probably design oh it doesn't finish it hangs so maybe you have to close the database or something yeah probably have to close the database i don't know how that works but so i think in the docs is there something on this yeah yeah db closures yeah yeah okay so let's so i think we could do something like this we don't need the result of this so we can unlock close on our db it's okay now it'll be my birthday 14 july ah okay is that exit oh close close connection that was it because they closed con in their documentation they used db both for the for two things i think so okay a little bit confusing okay so let's try that one last time um okay let's say so whose birthday do we know mark and he he was born first of january yeah okay nice i know that nice that's nice now we're saving a birthday and we're asking the questions now the last thing to do is we need to make it so that we can get notifications of the birthdays we kind of need to get input we need to run this either way you list the birthdays or run this where you store a birthday we need to uh pass it like we need a posterior command line which is like a list and yeah that will list the birthdays i know that you have um the tool cli package in mbb so you could create um arguments using that like we did in the the basket video but there's also another way to get all the arguments so i'm just going to wrap this in the function when it's the final function here i'm going to call it um create birthday entry and then i will just run this okay yep star come online yeah that one yeah so if we just run this we are in yeah we get a list back and it's a little item in the list so if we go first here cool let's list so what we could do here is we could make a condition and we can go if first if this is equal to list then we could list birthdays else we'll do our great birthday we're on our page okay entry function yup so if you run this now add all this birthdays function in there sweet yep obviously i figure out how to close it okay so let's make a function called list birthdays and we'll need the current month and the current day so we can go let month and we can get that from for a moment also so i think if we just go dot day on a moment entry uh-huh yeah we'll get four so and then that month should give us the month it gives it but it's an integer now if we go moment dot format and format takes in a string so we'll pass a string to it of four big m's cool that's exactly nice and but we needed the day and then the day is that day for a moment now we have to query so let's say find birthday entry or entries and this will take in just a day and a month and i'm just going to copy this because i think that's most of the logic is there oh no not that no the database thing yeah database thing yeah so let's copy this and post it in here so we connect to the client we get our db we use that collection now instead of searching we want to query so how do we do that so we just do find probably and then an object that matches those keys that we were trying to yeah so yeah exactly it's super easy that's nice so we can create a query here let's do that so the query would just be a javascript object and where the month is the month and then the day is going to be the day and i'll just convert this to a string and then we once they're running insert we'll run find on our collection query yeah and then we have a response oops and we close it then we get the response and let's just see if that works so get rid of this so we'll create a comment find with the entries um so we know we have one for one january oh yeah then we need to use a all right okay find cursor and then we have to do something with the cursor so we get the call to array on here yeah but maybe maybe you have to do it before you close it i expect yeah else yeah it's probably some kind of lazy thing and you have to do it in two steps because of this promise stuff i think oh no no i think it's changed it yeah oh okay okay yeah that should work okay that should work yeah yeah yeah yeah ooh nice okay that was really cool okay so if we convert this to the pivot there we can we got our day a month let's just format this and for each stuff maybe yeah birthdays yeah yeah whatever entries and find that the entries for day and month cool so we have our entries now what yeah so then we have to format okay so we actually should format them so now this function should probably so it's going to get an object like this so we can map over this so let's map over our entries with a function there's a function and we can call this this will be the birthday first we could just print it here so you can print yeah but this will be uh object this is javascript object yeah but we could first convert all of it to closure script maybe entries and then another entries that uh converts it to closure script so we'll have our entries and then entries would be so javascript two [Music] and we can actually let's just print out these birthdays for now and let's again run and comment list birthdays oh okay okay we have to run this with the weight also yeah but uh since you're printing it doesn't really matter probably but uh the print output uh goes to your wrapper window but we could instead of printing we could just uh return the value and then inspect it in a rapple okay let's do that just uh well we could just return entries then oh empty yeah because we don't have birthdays for today right yeah so let's make a birthday for today whose birthday is it today all right let's find uh is there a celebrity on wikipedia or something i'm sure today it's famous birthday on this day okay i don't know me anybody okay they're pretty old well it's a dutch painter so oh okay so okay works with you uh where's the where's that yeah cool i'm happy with that whose birthday is it yeah that one and it is seven seven of april right now we can evaluate this and we should see his birthday here yep maybe does it work okay check if we send the right data to to find birthday entries or or maybe call find birthday entries with oh yes yeah call it with it's the 7th of april okay that works yeah so we must be doing something wrong and how we can test that is uh by creating a temporary variable in fine birthday entries uh where we where we print the day in the month or or save the day in a month or maybe we could just print it like prn and then day right right day month yeah and then call it from the terminal and see what we get from the terminal oh we can also do that uh yeah yeah let's listen yeah i have the way with the print go so yeah it would go to your the rebel window i don't know where it is but we can't but since we're in the rebel oh okay uh before april so that's right seven oh wait that number is very wrong oh no no no for april today is the seventh april four how do we get four what is the order of the arguments in find birthday entries is it day month yeah it's a month it's so we're getting the wrong day for a moment oh that's weird yeah so let's see let's see what's the weekday it's the day of the week maybe oh yes so we're recording this on a thursday so we need to format it as d no no yeah sd i think uh no i i think we maybe should call a different function like month day or something day of month yeah that one nice okay day of month day of month that date okay so it's not the day what's that date what it was dates are very confusing yeah but um so let's evaluate this now and we should get what we want oh no no because i didn't evaluate this function okay and it's yeah okay cool nice so we should be able to then print maybe the name and the day as an end the month as a nice table i don't know yeah so we can should we print it inside of this function so if we go print so we can get the keys on this and we'll have we can cut we can get the so we can say it's name the comma string here birthday today yeah and maybe maybe we can instead of map we can use a function called run exclamation mark because we don't really need the result of this thing so what yeah what yeah what ron does is just run over with this function over this thing and do something so yeah okay that's perfect and then we also really important we need an emoji here click nice yeah now i think we don't need prn here because it will print a literal string now we can just use print line uh yes exactly yeah you're right okay and now we can run with list we can run oh there is an error because i see a linter thingy so we are missing a parent at the end probably yeah yeah okay so now that we have it you can run this birthdays save this and run with list oh yeah yeah that's cool but actually it's pretty cool looking for bird maybe we can change this to finding birthdays yep and then also use print line there i guess oh yes so prn is more like for debugging and print line is more of a human consumption i would say cool yeah i think that's it yeah yeah we're done we're done let's um but i think let's push this to a repo and then you can show us how to package this yeah like a nice application so maybe with mbb yeah okay let's let's put it in a repo but before we do it maybe it's nice to get the password out of the code and put it in some n file or yeah okay sharing passwords and repose is not the best idea so yeah we should we created a emv file yeah or yeah okay env and you would have like we'd create a new git ignore file yeah and we'd add our dot env here we can also add the dot culver yeah clj kind of maybe keep it yeah for for sale the econo you can do uh dot cash only so that's the only thing that you have to ignore from uh sale the condo so yeah okay so if you if you type dot cash without yes because it's a dot cash file and because the lsp directory also contains a dot cache file so you can do them both with uh this one thing oh cool okay and um what else should we ignore we can ignore the node modules yeah i think that's interrupt n n rebel dot enrollment port yeah okay that's probably it cool and let's move so let's move the db password and db username so maybe we can do b man db and b man i don't know db user and b men yes let's just copy those out okay and the user is cool and we can get rid of this well we can we can uh leave those in but get them from the environment right so js slash process and then dot and i think with capital letters uh and then the name of the environment variable yeah and then dot with uh right so exactly and uh i don't know does vs code have support for this dot end file or how does that work i don't know i don't think i think we'll need to use something you can uh if you start we just code from your terminal window then probably it will work right if you press code dot and then yeah so now it should still work yeah if if you have some dot end plug-in right i don't know if i don't how that works you don't uh i i haven't got this either but we can also do it manually then we just say bman db pass is and we can default to to uh for the user we can default to nbv because that's not very sensitive so we can do r js process blah blah and bb so right if we have a value here it will use this one otherwise we'll use this one right and for the password we just pass it on the command line and be done with that so we can say on the terminal we can say bman db pass is secret exclamation mark one two three and then invoke the script thing and then is secrets secrets yeah um so bash has this special thing with uh exclamation marks oh yes so yeah you have to escape it put it in quotes yeah it's kind of can i put it in quick yeah or put a slash before it that also works okay let's escape it a backslash yeah okay andy d app.cljs wait can you can you evaluate uh js process n and see what that returns ah so we made a mistake there uh what what was it maybe yeah like this oh okay so that's small letters ah yeah yeah okay okay that was it cool right so now let's try that again nice awesome okay um also just sorry this is bugging me a little bit this full it's doesn't need a comma okay yeah all right so now we can push it to the repo see i have a folder called dev and i'm gonna clone it there birthday man oh it's it has a lot of detail i wonder if i'm sure i didn't exclude the node modules in this thing yeah okay uh this is actually let's see what how big it is it's actually 32 megabytes okay but i think npm has some kind of configuration for this to exclude all kinds of files so okay to make this a package uh we the goal is that we can execute npx uh birthday man or birthman like this and then list or something right yeah but so this doesn't work so how do we make this work um so first well we already have the package.json so birthman so if i globally install this this local project then i can actually in in another terminal let's see and now i can do something like this but it will say i i haven't found anything to execute so what you have to do is make an executable script so dev birthday man so this is our our code uh right yeah can you see it yeah i i usually have to have it to sort these things it's a little bit silly but that's good let me just try it locally if if it works so nbb app i don't have to install anything because all the node modules were already they're already there seven uh oh sorry no this doesn't make sense so uh john what day seven uh april and now it's saving but i don't have uh the password so i can do b man db pass is secret one two three and we have let's try it one more time so both john uh eight february now it's saving yeah that worked so as long as as users have this password they can use this app but now we're going to make an executable script i have to peek a little bit in the nbb project because nbb itself does this so um it has a package.json and there you can say main or no actually bin so it says this this is the binary file that you should execute so let's put that in our package.json on the bottom bin and then we say birthman and then we we yeah we have to have to make some kind of javascript file to execute this and to take care that nobody has to first execute nvb or install nbb locally we can include nbb as a dependency oh we're already in package json so what we can do is dependencies we'll just add nbb itself as a dependency uh it's actually there there's one newer 033 so what you can do now is make a wrapper script in this project called index dot js for technical reasons you actually have to name this mjs because it's it's an ecmascript [Music] convention so so we're going to create an ecmascript javascript file and we're going to say import nbb import load file from nvb so this is javascript javascript mode okay so let's try that for a moment um npx birthman let's see if that works let me install it globally and see if that works yeah so that worked uh but if there is one issue that it doesn't have the node uh so i don't know why but for some reason i have to do this myself um okay so i don't know why but maybe if you install it via npm this happens automatically or something i not really sure but let's do it manually now so it says cannot find the package nbb that's because i didn't run npm install after i edit the npm nbb dependency so now it worked as you could see but but we still have to execute the app right yeah so what you can do now is await load file and then call app details yes let's see okay cool that works so whose birthday is it blah blah okay but when you uh install this globally then npm install minus g it will install the local project globally and in in another terminal if i then ran run birthday man then it won't work i will explain why because it tries to open uh relative to the installed package oh yeah and so you have to fix this as well if you want to deploy it as a package so what you can do is uh i have documented this in nbb so it's called pub publish i think publish an nvb project to npm so here i describe how to do this it's a little bit boilerplate but you can just copy it so i'm copying this part which so this their name is the relative directory uh relative to the installed package so i'm going to get that this should be enough resolve resolve their their name and then app.tail yes i think that should work so it's a little bit boilerplate but it's worth it if you go to npm with your nbb script so as you can see it now works so if i would now um so i'm going back to the nbb package.json and so pax.json has has a thing called files and these are the only files that are going to be published to npm so let's use that and then we don't have to worry about modules or all kinds of garbage in our project that ends up on npm so what we want to publish is the index.mbs and epsilon yes that's probably it so i hope i didn't make a mistake uh but now we're going to publish this to npm so yeah i i've never done this before so i don't know if there is already a project with birthman npm what what was the command for this again npm publish or maybe just npm publish so and birth man uh so so if if i now do uh npm remove minus the birthman it should be removed globally so no i will find it it'll find it on npm so px proof man it will fetch it from npm now because i removed it from my global file system so then it will search on npm or is there a package yes there is okay let's do it install it okay i hope yeah so now it you see it executes the script let's test it whose move is it well mary what day eight and in may saving but now it it fails because it doesn't have the password obviously so that this is the thing that you then have to set in your enviro local environment uh thing but that's it so here you see we we packaged it and it's only three kilobytes so it's it doesn't have all the the garbage so yeah cool that's yeah that's way easier than i thought it was going to be that was red cool man i think it was is that the video we did it we did it
Video description
Hey guys! In this video Michiel Borkent and I create a command line utility to manage birthdays using ClojureScript and Nbb. - What is Nbb? Nbb is a tool Michiel (borkdude) created that allows you to write Node applications using Clojurescript. - What are we building? A utility works from the command line and allows you to input a name, day and a month and store the data on MongoDB It can also query MongoDB and let you know whose birthday it is for that day. // Final Code https://github.com/danownsthisspace/birthman // Nbb https://github.com/babashka/nbb // Create Password manager using Babashka https://www.youtube.com/watch?v=jm0RXmyjRJ8 // Inquirer https://github.com/SBoudrias/Inquirer.js/ // Moment https://momentjs.com/ // MongoDB https://www.mongodb.com/ // Links to all libraries are in the repo GitHub repo: https://github.com/danownsthisspace/birthman // Babashka https://book.babashka.org/ // My VS Code theme https://marketplace.visualstudio.com/items?itemName=BeardedBear.beardedtheme ----------------------------- 00:00 Intro 00:26 Install Nbb 01:32 Setup Project 03:24 Start a REPL 04:47 Import packages from NPM 08:57 Run the script 10:20 Outlining our project 11:33 JavaScript Interop 13:30 Dealing with promises 16:12 Getting fields from JS objects 18:32 Convert JS object to Clojure 21:17 Validate Input 23:00 Selecting a month 25:52 Connect to MongoDB 32:00 Inspect data returned from a promise 34:00 Write data to MongoDB 39:53 Query MongoDB 48:21 Debugging 53:00 Use env vars 57:50 Package and deploy to NPM