
do a little let’s code where I poke
around
add some features refactor an app that I
have and we’re going to do it with a
theme and that theme is function
composition we’re not only going to do
function composition but I I will try to
show a lot of it
I am mpj and you are watching fun fun
function so what are we going to do
today more exactly well a couple of
weeks ago
fun fun forum was launched which is the
main patreon reward for patrons of fun
fun function you can check out the
information more about becoming a
patreon patron by clicking there you
don’t have to be a patron to you enjoy
this episode at all that is just
completely optional but that’s the
context so there is this fun fun forum
calm and this is a discourse forum so it
has a really great API and in the in
ddddd project ideas section no it’s in
the FFF meta so this is somebody had the
idea of somebody
it’s he has a name Valis which is a
four-member had an idea that we could
have a map where all the members of the
forum code if they want place themselves
on a world map and it looks he actually
built it and it looks like this wow
there’s a lot of people this is very new
this was like milk yesterday and well
okay so it has these overlays this is me
as a good moose which is something you
tend to say in the city where I’m in and
here’s Theodore on parental leave eating
meatballs at my IKEA table and over here
is people in the you
what is this even what what is this
country I don’t in order for this work I
kind of threw together the world’s
happiest API so it works like this
because it’s so done but it’s so fun you
go to your profile on the front run for
it and here now I’ve added a custom
field in this course called hackable
Jason so what will happen if you put
data here so you put Jason here and this
data will be made available at this
endpoint here this this is a public
endpoint that any anyone can access and
so this is just a Jason in the JSON
objects tied to user names so my
username is here you see like user map
location map longitude caption get moves
and this is like super hostile ADA I if
you look here like people have immediate
we’ve tried to do scripting attacks
inside of them so if you use this make
sure to sanitize your inputs and this is
not mean people I’ve actually told
people here to putting on JSON data here
is to break to break the apps of other
members is highly encouraged to teach
people to sanitize their inputs on a
link to this great xkcd comic which is
about a little bobby tables do you
really name your son robert drop table
students x case it is so good but that
is that is actually not what we are
going to talk about today this is as you
see here this is the forum Automator on
Heroku it’s a really hacky project that
I just threw together really fast during
the during the night of the patreon
launch because one of the rewards for
the early bird patrons is that if you
become a patron during the 31st of this
month which means until until
I don’t know dates I did look in my
calendar until Thursday is the last day
you get this special batch that nobody
else gets let me show you one example
let’s say lamb neck here he has this
special forever Eternity member so let
me show you that I’m just gonna go to
some let’s go to introduce yourself just
pick someone here look at the fing Shang
here so notice here that Feng Shang has
this special forever eternity member
badge and this this is only people that
join August they get this and this is
what it turned out that there was no
functionality inside of this course to
do this automatically so we were just
clicking and assigning this manually for
every new member which was just crazy
because so many people became patrons
and joined the forum I died but like it
was way more than we anticipated so this
turned out to be a huge pile of work so
I just I’m programmer we got a code this
and that is why I why I ended up
building this forum Automator
and then as someone asked if there was
an integration point to build that’s
this map functionality I just threw this
together because I figured it would be
fun because it’s very easy for people to
build build new things on top of this so
what we are going to do today is you
notice here that this is an introduction
thread so this is a threat topic that we
are I’m sending people to this so in the
Thank You page for the patreon it says
that oh you should first thing you
should do is go to the introductory
introduce yourself a topic on fun for
forum and write a little bit about
yourself that’s just a very nice little
thing to do and I this is great but what
I would like to do
is to have a extra badge here that says
introduced and have the bat badge linked
to that to the introduction post and I
think you can do this because there is a
blah blah blah let’s see let’s see how
this works if I do it if I do it
manually
let’s just go to fun fun forum calm and
let’s go into the admin see click admin
see patches hmm how do I do this maybe I
go into the user and I go to badges here
perhaps oh no I have to click admin here
I think Eddy badges see what you can do
badge API test dodge reason oh yeah this
is this is the functionality you can you
can assign badges and then you can also
assign a reason which is a link to a
post or a topic so let’s first create
the badge that we we want to assign to
people that have introduced themselves
so introduced introduced and badge
silver always gold I suppose
group other description longer
description and this is the badge that
you automatically get when you introduce
yourself in the introduction thread
topic um you know like in discourse
threads are called topics but I can’t
make myself say topic I’m so used to the
old PHP BB and vbulletin world where
they were but what whether you would
call threads I always remembered this
meme hey guys what’s going on in
thread these ones hey guys what’s going
on this friend
hey guys what’s going on what is that
even oh it’s it yeah um okay so now I
think we have the a little bit about
Orion true goose no oh I haven’t made it
yet I was in the wrong tab long
description I don’t clean it a long
description uh who needs long allowed
badge to be used as a title so this we
don’t need that can be granted multiple
times no sure Bertram public badges page
yes show post granting badge on badge
what what post granting bet your badge
page yes yes we want that that is the
whole idea and we also want to enable
the badge it’s not disabled in the
system because this course comes with
this insane amount of baddies I really
like the default badges and they are shy
so I’ve disabled them all make
introduced exclamation mark at some
point I’m going to create an iPhone but
that’s not what we’re gonna do today
because we want to get to coding either
way let’s try to assign a badge to to to
this person where was Frank shine okay
a blue little chin I go to his username
Oh
click click I mean and somewhere is the
badges badges introduced I want to
assign a reason for that interaction
let’s find the interaction post do use
yourself and it’s fine Feng Shang did
this one how to find the link to the
post is this yeah let’s click this load
one
and I placed this in and I grant it
let’s see what that looks like now this
oh yeah it like updates that is a very
nice feature with this course compared
to the horrors that is the youtube
comment system that things update
automatically so if I click here I come
to the introduction yeah not the nicest
I thought that the flow would be nice
early I if I click introduced I go to
this and then this is the reason but at
least but what I want with this is a
reasonably easy way for if somebody has
written an introduction telling a little
bit about yourself I want other members
to be able to find find that post
reasonably easy without doing all kinds
of magic and this this thing I think it
does the job but again I don’t want to
do this little dance for every single
user so we are going to automate this
using the before motivator that we are
using for all kinds of things two things
actually but this will be the third now
I’m going to show code in just a little
while but first we’re gonna talk about a
little bit how we’re gonna do this so if
I jump to API here it’s immediately
going to show you that my secret API key
which I will regenerate after this this
video so yeah anyway this is not where
we’re looking at we’re looking at web
hooks here and so this course has this
thing where you can set up web hooks
which it will post to post data to every
time something happens on the forum
someone posts something someone updates
their profile whatever it all goes to
this this web hook here and I can
inspect some of the payloads here and
perhaps I can go into this hopefully
nothing secret this is a
post created thing and it’s it’s a new
post by Christian and and stuff he has
written oh he has supposed it to the he
has submitted a video to the be a part
of the fun fun forum welcome video lots
of stuff happening
it’s a deadline today Sunday where I’m
recording it on Sunday so if you’re
seeing this it’s too late to be in the
video uu sorry about that but this is
the way it’s post this huge JSON blob to
the to the web hook and this web hook
it’s so stood here for moderator schwarz
web work and that is work we are going
to take a look at now so this is the
code for the web hook if you are used to
express this will not look particularly
strange Express is a app development
thing for doing back end things with
note it’s it adds a lot of useful
functionality on top of vanilla node it
has a lot of JSON parsers and early
coding stuff and it handles across
domain origin security things which is
disabled there and yeah stuff like that
it’s it’s useful what it’s not standard
here from the normal Express setups is
that you see this wrap function here
that ears let me jump up a bit because
I’m doing dependency injection here
look to index see rap so this is called
express a sing craft and all it does is
to allow me to use a synchronous
functions and instead of the normal
request response so I can do a weight
here if if you want to check out a sync
weight functions I did an episode on
that last week or two no no the week
before that either way you can click it
but link it back finally if I click in
there I’m going to go through this
function in a little bit but I notice
here that it’s not working I have this
thing here that checks for the validity
of its request valid but the thing is
that is request value that’s actually a
function that is supposed to be passed
the request but right now I’m just
checking out if it’s false which it will
never be and then is routed so this will
never get hit because is request valid
will always exist because it’s a
function so we need to do that but not
right now
why don’t you do it so what this code
does is that it let me close this
sidebar is that it will accept a a post
to slash webhook as you see in the forum
in the webhook section see that this is
the destination of the the post that
receives receives all the data and it
will check the headers for this this
special header called X discourse event
so if there’s a user created it’s going
to pull out the username and created at
from the body of the user of the payload
it’s going to extract the data in month
and then only assign the spatch for
people that have joined in in August
then I’ve hard coded this special
forever batch ID here the call
why I was lazy at the time and yeah I
was not lazy I was being time efficient
anyway
I call this function here a sign badge
and it takes a an object object later
with a username and a batch ID and it
passes in this special forever batch ID
and once it’s done with the assigned
badge it’s doing a console log saying a
science project for every badge do you
username and then it sends status okay
unless there’s an error which then it
will console.log the error and then it
will do a response status 500 it does
more stuff here but you know what we are
going to disregard that for the brevity
of time I will I will probably put this
put this up on github so that you can
can look at it if I decide to do that
the link is in the episode description
what we are going to look at is to look
inside a sign badge here so let’s open
that up and let’s see a sign badge Wow
I’m using you should you sing Visual
Studio code if you’re wondering what
editor I’m using I don’t particularly
recommend it or not recommend it it’s
just an editor I use I like that it it
there’s nothing you have to install it
just works pretty well out of the box
and this this is the assigned badge
function it might look a little bit
funky if you’re not used to inversion of
control because I’m doing a bit of
dependency injection here if inversion
of control is a new concept to you and
especially if you haven’t done it in
JavaScript or maybe not at all you can
check out my episode on inversion of
control by by clicking here it’s also in
the episode description but just to
briefly give you know where you want
what I’m doing here is that this make a
sign badge here it is not the actual
badge function it creates the assigned
badge function after you pass in its
dependencies so as you see here in this
this function here is dependent on these
two functions so it needs post as the
ACE on two and it needs the discourse
API are in order to in order to function
it also needs error unless okay but that
is that that doesn’t have any side
effects or state or configuration
options so we are just requiring this it
doesn’t need to be injected while these
two need to be injected I’m gonna show
you how that works
hang on dg2 Jean Jean Jean so if you
look at let’s find the assigned badge so
this is where we create the assigned
badge function so this is actually the
assigned batch function this is not the
factory or whatever you want to call it
like this is this make a sign badge it’s
what we call whoops wrong file is what
we call here so you see here that we
require a sign badge which will be the
factory function and then we pass in the
two dependencies into that function so
and these are defined elsewhere so this
is their passed in here anyway
what is happening here is that we make a
body this is what you are supposed to
post to the discourse discourse API in
order to assign a badge there’s a user
name and batch ID and let’s have a look
at the documentation what I will do this
scores API and circle badges here assign
a Bachelor user oh it’s I think it this
is a we’re documentation system they
have I don’t know exactly what this is
it’s funky no Cece you’re like it loads
all of it and I think that these are
gray because it hasn’t loaded the
documentation yet does anybody know what
this documentation system is this is
open API specification waiting there
finally assign about your user there so
it has three three parameters a username
a string and the batch ID and in and
then there’s a recent a string so I
suppose this is then the link to the
post yeah so anyway it creates that body
and then it posts that yeah that body as
adjacent to and it posts that to the
discourse a PIL user bad gist of JSON so
what this function does is that it
actually created takes this API path and
then it actually wells on the HTTP
funfun forum comm slash and then it also
appends on the keys that you need to
provide let me show you that function
real quickly so you see here that just
text base are this is the path that gets
and then it wells on the query string
which is from this query object where we
have this this API key and this API
username and this works also exactly the
same as the other functions
it also has also dependency inject it
has its dependencies injected see see
her that fetch is the is not actually
required in here it’s it’s being
injected and I also inject the API key
and the base Earl into the function as
as dependency so the configuration is
dependencies into this course your I
[Music]
clicking around where was I oh yeah we
were in a sign badge so after it posts
it as to the did this end point it will
error unless unless okay and errorless
okay is a very simple function let me
jump into that it it just takes it
accepts it’s a function that accepts a
response and then once that if that
response status is not okay
yet oh I have added a dirty login
console log here that will move just
throws throws an error otherwise it
resolves to the response anymore and
that is basically what make a signed
batch and does this are part of this
piping function here on Ram de it’s
probably going to be very confusing to
you unless you happen to watch my video
on the new echo scripts or proposed echo
script pipe operator we’re talking about
piping and composing function you can I
direct you to a lot of videos now but
you might want to check that out i it’s
you can find it here or in the episode
description it’s pretty cool but what it
does is that it combines the
these functions into one and then and
then returns it then we’re going to be
working a lot with with this today I am
thinking about where to start do we
start at the bottom and extend this make
a sign badge or do we start at the top
you know I think that we want to start
at the top
oh wait wait wait so I’m going to go
back up into serve which is the Express
application itself and dddd dddd so we
have this user created event we want to
look at the post created event I would
like to find out exactly how that event
looks and the easiest way to do that is
to actually just make sure it happens so
I’m just gonna do a dirty thing here say
that introduce yourself I’m gonna create
a reply Here I am testing and API
integration thing don’t mind this toast
Oh reply and then we are going to jump
back into the admin to the web hooks and
then jump into this web hook log and
find the request here this should be the
one and that somebody was really fast no
this is the one so this is what we’re
looking at and go to just to be clear
here like clear secure or something go
to paste this into a file and I’m going
to take the payload here I’m gonna paste
that in to down here so that we have it
example host created txt whatever and
and if we look at this we see that it
has this a X discourse event post
created so let let’s begin by stealing
that could be facing that and it’s a lot
of if statements bytes
mmm-maybe turn that into switch later or
something I know
else if hmm I wrecked
oh let’s piss on it and then we slip
take and grab this here this is this
application so far was built very
quickly so it’s very dirty hacking we
might add a little bit of you start
adding a little bit of unit test to this
app because it’s it’s becoming complex
quickly that’s the thing with unit tests
you kind of when you’re super stressed
out and you need to get something out
fast you tend to tell yourself well this
application it’s yes this simple thing
it’s it’s not gonna it is not
complicated we I don’t it’s just one
path I don’t need I can test it manually
for now and then it gets gross in do
complex things very quickly it’s just
it’s almost always better to just add
unit tests from the get-go or you just
save so much time anyway I didn’t do
that let’s see what this looks like
okay so request body user blah we want
to body don’t you know what it’s not
it’s not user right it’s something else
it’s a post so the post contains stuff
circle quests body posts so we have the
post paid
I’m inconsistent with left and Const
here too – our camera getting torn on
the whole Const kind of right now when
I’m just doing my own projects I’m in
the face where I use let a lot because I
just want I like the idea of non
mutability but it’s not like they are
completely immutable and I like the idea
of just having one variable keyword a
sidenote um on jumping between files too
much here sorry people let’s go and
check the data here what is it that we
want we want to see if this is a post
first and foremost if this is post in
the introduction thread topic
can I see what topic slug Oh awesome
here is actually this is great this
topic slug here introduce yourself don’t
think that that will change this is not
industry grade programming we were doing
in their hair but see introduced
introduced yeah we are looking for the
topics like slow was that right topic
slug yes if post topics slug is
introduce yourself then we are going to
do what then then we know we now know
that we have a introduction post so we
want to create a batch for the user that
created it
so what we need is the user name of the
user to begin with its thing
yes post it’s right here very handy it’s
pom pom pom we can start extracting
we want the topics log I don’t need that
anymore so now we can actually start
using this function I wait a sign badge
sorry awaits a sign ah so so sorry I’m
just jumping around like a squirrel
signed badge and I’m going to close this
sign bar so that we aren’t not
distracted I’m going to assign the
username and we’re going to assign the
batch ID you know what I’m just gonna
batch that I created before where is it
found it and it’s ID 104 copy that and
paste it let’s keep it here for now
actually let introduction introduction
badge ID equals 104 I pasted it here and
we now want to pass in also the the link
to the to the post itself here so we
need a reason and this is linked here
post Earl but this does not exist yet so
we need to figure out where to get that
because where where where where where
where where so let’s look at the example
Taillow that I captured from before okay
is there a link here somewhere
bla bla bla bla bla bla no there’s
there’s not a handling and it makes
sense I suppose but there is an ID so we
can construct the the post link I
suppose let’s have a look at how they
are structured let’s find this link here
let’s copy this link sorry about the
Swedish operating system and then
pasting it in here hmm okay there’s a
lot of stuff in this hmm well you know
what is this 23 so I expected there to
be that desk to exist but I don’t know
exactly what this is is this the post
the word is this 23 yeah this is the
post 23 what happens if I start removing
things here if I grab this and I remove
that what happens oh no no no this does
not work hang on
this is the post number okay so I need
the post number and the top bit here’s
the topic ID we need that as well and we
need the topics long do I though can i
let’s say if I scroll down to the bottom
here and I copy this linker and I move
this you user mpj we probably don’t want
that guessing if I just remove the topic
slug here don’t really need that for it
to work
no I did it added that by itself let’s
actually just try that again to make
sure yes cool that is just some search
engine optimization thing it’s doing it
looks good so I’m need to extract the
the topic ID and the post number and
that will work as the work for the Earl
so we have the first number and the
topic ID under your underscore so I’m
just gonna hang up so fake ID and the
god I remember like a goldfish post
number there we go and the post Earl is
going to be to delete this we don’t need
this log for it to work and we don’t
need that either and I’m going to make
this into a what’s this called template
literal thing string either way I can do
put in variables and string like this
and the topic ID first then the post
number go do you think there no there
that is the post Earl I’m gonna leave
this hard-coded in for now it’s it’s not
too bad this is not going to be
developer of the Year thing don’t worry
we are going to add a test to this but I
don’t I it I’m a big on big on tests
first
in many situations when I have control
over the entire function what it’s doing
I really like doing doing TDD but in
cases like this where I’m so uncertain
of the of the API I tend to find that
it’s better to hash out what it is that
you are doing and once you figure out
how it works it’s better to add add the
tests because you just don’t know the
thing well enough to do a test upfront
either way there however there is a case
here if the topic slug is not introduce
yourself we don’t want to do anything
with this we don’t care about this this
particular post created events we don’t
care about all the other posts in the
world so we are just going to return
status 200 carry on it’s a lot of
duplication of this right now in this
code so we’re going to have to do
something about that eventually ah but
if you’re new to my channel you’ll know
that I am big on waiting on a lot of
duplication before removing it because
that will allow you to see the general
case much more clearly and it will allow
you to make a much better general
solution than if you just prematurely
generalized as soon as you saw like two
next step next step next step you know
what I think that the next step is
actually to break this out and get it
and get it under test however I’m not
super sure what the what the interface
I’d say like we let’s imagine that this
was a function function group and we are
going to call it cool it’s something
like handle post created I think pom pom
pom pom and since this is a factory
function this needs to be a factory
function because it has dependencies
it’s dependent on a signed batch so we
have to do the inversion of control and
inject it if you don’t know why you are
going to understand why in a little bit
when we write the tests for it
see okay let’s say common left may
handle post created and did it has a few
and I think that’s the only dependency
and the actual function will have a
signature what does it need it has the
introduction ID inside of itself and I
think we can keep it there this does not
need to be configurable this will not
realistically change post Earl it
creates that on its own it needs the
username it needs the topic ID and it
needs the host number and it also needs
the topic slug to know if it should
should should assign a batch if it this
is in the and in the introduce yourself
from in this in the introduce yourself
topic okay so the arguments are bum bum
bum bum bum bum
it needs a username it needs the topic
slug it needs the post number and it
needs the topic ID this is what we’re
working with this is the function that
we are going to write I am actually you
to know what I’m just gonna copy this
here first in I’m going to just paste it
as a comment is to give us a reference
implementation of what we are building
once while we’re writing the test and
I’m going to jump out of this file and
this copy it and I’m going to create a
new file I’ll paste it in here save it
so that we get some syntax highlighting
and you can see it but I am calling this
handle post created dot j s so it’s now
here what this is also getting a bit
messy
I’m keeping it messy until I have
decided on a structure that makes sense
I’m not trying to structure too much up
front I’m waiting for the structure to
merge a little bit otherwise you tend to
just place things in dumb structures
that are hard to change later anyway I’m
going to do handle post created dot test
dot J s going to do just a mocha test
here to start test mocha Oh
no hang on handle posts created and
mocha does this thing where its
functions within functions and stuff and
then mocha test case looks like this
just like I just want to see get mocha
working because I don’t have mocha in
place here should not fail now pull up
the terminal because Visual Studio has a
built in terminal I’m gonna do npm
install save I’m going to package.json
[Music]
and we’re going to add scripts I’m going
to a test don’t you add Boca can I just
do this I think that mocha will just
find stuff with dot test OPM test could
not find any test files matching pattern
test let’s do like star dot and test of
jazz no yes that worked
let’s keep it like that for now the
reason why I created this npm testing is
that i i didn’t install mocha locally i
just installed it in the in the
application so if i type your smoker it
will not work because it’s not in my
global scope however when i do this have
it in npm scripts here it will have
access to mocha in in the context of
running this because npm does stuff
internally it’s really handy and it’s
it’s nice do not have to install market
globally either way let’s close I have a
lot of things open here let me close
some don’t need that don’t
don’t deserve at the moment I’m gonna
save it cool so we have have a post
credit it should not fail because it’s
what to do
mocha don’t watch I do that it’s not
work oh hey I have to fix the picture of
Jason thank you to watch let’s try that
NPM test it’s cool now I think it runs
every time I change to the file so so so
so so so so so what am i doing oh let
handle post created the function that
we’re testing we’re going to require it
it a boost created and let’s have a
setup here before each so this will run
before every move to every test case and
we’re going to have handle post created
remember that this is actually the
factory that makes handle post created
functions and I’m going to assign kind
of course created with make handle first
created calling that and then we pass in
the dependencies so in a when we are
going to be using this and real
application we’re going pass and the
real dependencies I remember the only
dependencies that we actually have here
is assigned batch bom-bom-bom and a sign
that is a dependency because it will it
has a bunch of bunch of side effects and
boom boom boom so we’re gonna fake that
put a sign batch and we are going to
need Zenon Zenon is a thing for mocking
think it’s just enough many crashes
because sanam is not installed so it’s
no so I’m doing a lot of things here
then I’m not necessarily spending a lot
of time explaining if you have questions
you just post them in the comments down
below there’s also a most we’ve got a
personal link to the discussion thread
about this episode on the front on forum
if you are a patron where you can like
ask questions about the nitty-gritty yes
remember when you ask a question make
sure that you link to the time spot so
that people know exactly where you what
you’re asking about
blue blue blue blue
all right see no requires you know how
do you do this is it I think it’s just
seen on dot stop sometimes I remember
things and I call it a sign batch so I
sign this to the dependencies so now we
have like the actual handle post created
function and when we call that handle
post created what are we testing here
it’s just it can be cold let’s just call
it and see if things work now ah NPM and
BM test and make handle post created
it’s not a function okay let’s look at
the code now it’s true because we are
not not exporting it so I know you do
more Joel dot export
because mechanicals created cannot match
against undefined or no oh yeah
so handle post created it wants an
object and it doesn’t it’s in it isn’t
getting an object it’s getting undefined
so we need to pass on an object and now
it works so so we get chemical we’re
getting somewhere
but we looking at our sketch here we
want it to call a sign badge with this
stuff here so let’s go look at it calls
and we wanted to call it with the
username that we passed in we can start
with that with the username passed in so
let’s call handle post created with the
username with a username username and
then we’re going to that we need even
try that
okay all right try it seems to have
improved okay so a sign expect the mock
the stub a sign badge how does it work
and season expects ah yeah expect wise
hold width is that it I think that’s the
argument and objects I called it should
be called with this straight up was it
expected stub to be called with
arguments
what’s it though no it wasn’t we need to
actually call it so that the test works
assigned badge I sorry a signal sign
sign batch username and now it works
okay we’re making progress we also want
it to assign to pass me calling it with
well I’m just gonna bake these
properties together with correct
properties to do batch ID 104 okay
we see here that it’s now failing
beautifully that oh this is incorrect
we’re calling it with some user name but
it’s like that it you call it with batch
ID 104 and usually in some user name we
need to fix the code is useless here
folk badge I D and it’s passing next up
is that we want it to provide the reason
right it’s supposed to look like this I
post paste that into the test reason and
it wants it to have topic ID and toast
number yeah so if we call this where the
topic ID 5 or 5 and post number 66 it
should assign the reason 5 to 5 and the
post number 66 cool and it’s failing as
expected we go back to the code and do
the actual thing here
topic ID and post number whoops
needed that thing here and of course we
need also to assign the reason to the
object and it’s now Pat saying cool I
right now we have an if statement here
we don’t want to do the assigned badge
if the the topics are isn’t isn’t
introduce yourself so let’s make sure
that it does not call a sign badge if
not correct topic log I like to
capitalize the not in in descriptions
because it’s hard for humans to deal
with negation so he makes it you makes
it a lot less likely for you to commit
mistakes if you like call out the
negation I’m a bomb so let’s say that we
call handle post created but we have a
topic slug that is something else than
topic slug then I expect a sign that was
[Music]
expect object method was called yeah
okay but how do i oh not was not cold
like that yes that worked expect this
stuff do not have been whole but what
called thrice what that’s that’s
unexpected
oh it’s because I’m not I’m using
reusing the stub between each tests I
should recreate the stub each each time
let’s do that okay it’s still failing
but right now expect this up not to be
cold but what’s called once that’s
better okay so let’s go back and add the
if statement so that it the test stops
but I put that at the top I like to do
defensive programming like this and like
have things terminate on the edge cases
rather than doing them as Alice’s at the
end I heard some nice rationalization
about why but my brain does not work
well enough to to call that out either
way mm-hmm right okay expected stuff to
be called with arguments this is
actually the other test that is failing
so the tester we were working on works
well now but the old test broke and that
is because that doesn’t have a topic
slot so we need to give this this make
this call completely valid and what was
it called it’s introduce yourself see
cool I’m gonna drag this down a little
bit to give us more space okay next step
is that the assigned badge here it’s
actually just going away and doing doing
things we want to actually wait for the
error as well and the nice thing here is
actually that assign badge returns a
promise so we basically just want the
function to pass the promise on and
whatever code is using that function
will then be responsible for dealing
with the promise as we talked about this
is a great technique to pass error
handler handling up words I talked about
that in a previous episode that you can
find here but basically we want to make
sure that assigned batch just returns
let’s it passes the promise on to the
calling function function good yeah
promise from same batch on to the
composure
if they dip it dip it you it’s just hope
we paste this for now in tests it’s even
more important to just wait for
duplication to arise
I normally in code I wait for at least
three cases before removing duplication
I’ve found that to be kind of a sweet
spot for when you start to actually see
the the actual general case in tests I
found that you have to wait longer
identified the general case so I tend to
wait at least five or six times before
yeah what we’re doing we want to we call
us call sign batch we want to have a
sign that return something a check that
we get that out from Hannibal’s
regression so let’s eat let’s output and
we want a sign badge called
well no it’s just with arcs no we can
just do this returns
and we we have to do a fake promise so
like we can just use any object here
doesn’t matter it’s just a placeholder
Oh sign badge returns fake promise and
then we title and then we check that
output expect output out out output to
be fake promise I broke expected
undefined to equal this thing let’s I’m
gonna fake promise yeah so expected
I I am anyway I’m just creating fake
object here I’m trying to give it a good
name ahh good structure anyway expected
on the fight to equal I’m fake promise
because we are not actually returning
the assignment return a signed batch
does that work come on oh wait doesn’t
it oh it’s because yeah because it’s now
in the if this is for the case where
it’s some other slug it will introduce
yourself I’m going to change this to be
the correct response and now it will
return the the defect promise because
now calling assigned batch yeah though
though though though though what happens
if I want this to be reliably a
synchronous I always want this to return
a promise because otherwise it gets
really weird to call it let’s see let’s
and with returns a promise when when we
God God I am my brain is melting when
damn I’m just gonna copy paste this one
the incorrect topic slug and paste it in
here but this time we are checking that
the output I want left after coat pulls
out put top-10 should be yeah this is so
that you can do a synchronous test in
mocha just call the done callback once
you’re done I know that there are stuff
that you can call with you can return
promises to walk about it it’s not quite
I don’t feel like it’s trust words in
this case anyway it’s not it’s not even
getting this far because it’s it’s not
returning any promise I have to make it
return a promise so are you just promise
dot resolve true I guess
cool and it now works because yet it
resolves to anything we don’t really
care about the value you know what I’m
just
have it resolved to any value because we
never use it we just wanted to be
resolved and then it calls done and that
makes this test succeed if I hadn’t
called done it would have timed out time
don’t bump cool I think that we are now
our example code here I’m fine with this
and what I’m going to do is now go back
up to our mmm serve and find out where
we want so ok here is our where we just
wrote our stuff which we know now no
longer use we have extracted some data
from request body toast we want to now
actually call the function that we call
it graded handle post created and we
want to pass these things on we have
called them slightly different names
because these are underscored names and
in our system we are using the
convention of camel case and so there
it’s called topic slug instead of topic
slug mapping them around and topic ID to
topic from topic ID and then we have
post number to post number and I think
that will be yeah think we’re using a
sinker weight here in this at this level
then we are done really I think this is
it okay let’s let’s commit that
let’s find tower oh this is just a
crappy file let’s throw that away
example post created I’m gonna keep that
around just in case we need it a little
okay this is the thing I never fixed
let’s keep that around for now we added
a bunch of dependencies yeah looks good
all right let’s commit it what did we do
we implemented a sign introduction batch
and we push it to our github and then
I’m also going to do a git push Heroku
master this is how you deploy to Heroku
probably I get very nice it’s kind of
fast but this part is really slow I
don’t know why bootstrapping NPM it’s
just caching and stuff building
launched all right cool see if I broke
something horribly now let’s go to admin
and let’s see let’s go back to the
introduce yourself thread rushing just
for kicks do I have the introductions
patch okay I have this API test match
that is from some other test idea let’s
actually do a another test another API
test don’t mind me testing in the live
let’s see we’re so lucky that I got the
badge no why not okay
what happened to the let’s have a look
at the API and look at what happens to
the webhook so okay we got a 500 error
crashed so this is post created event
let’s have a look at let’s all look at
the logs Heroku logs logs this just
should give us okay hang on this is some
other stuff okay
handle post created it’s not a fun yeah
doh okay maybe I should have tested this
it’s not that hard when that hooks I
could just have pasts I have the entire
entire request hair I could simulate
this using curl or something I’m just
lazy yeah
okay so the problem is here that let’s
find the this thing this is not a fine
because it’s not defined what we need to
do is to pass it into serve so serve
gonna add this as as a dependency to
serve what is served
so serve is another one of these the
inversion of control functions that I’m
doing so the top level is actually not
serve it’s actually index so in index we
are going to hang on after sign batch
because it’s a it’s dependent on a flag
match we are going to do handle post
handle post created and again this is
not actually handle post created this is
the had a post great create the factory
function that takes our dependencies and
and it only has one dependency remember
yeah it’s dependent on the sign batch
and we’re so passing that in and then
handle post created because we need to
pass that in in to serve because serve
is dependent on how to post created that
is why we had a problem before and now I
think this should work I on and we’re
pushing that to get and we are also
pushing it to Heroku Wow
get push Heroku my stop
beat my stupid API integration things
yeah I can actually
retry this post created thing I just
take your redeliver and see if it works
this time don’t look
Oh lots of other things happening bang
bang bang bang bang reference and
reference their post number is not
defined at observe 59 oh yeah I uh I
could have seen that coming
all right fixing things boom pushing to
Heroku again okay
let’s strike it redeliver ah yes I want
here’s some RAM de
exceptions yeah I think I’m getting very
close to the point where I really should
be able to just fake these web hooks on
my on my own machine but I’m not quite
ready to do that yet I’m going to just
maybe opts we’re calling this horrible
production debugging and we’re doing a
gig for sure I didn’t actually log it
out oh my god I’m horrible horrible
horrible horrible horrible I’m just
digging myself into a hole here argh
at least I have commit history yet push
your master I realize during these let’s
go things is that I want to do it in a
condensed time period but that also
means I just show a lot of horrible
horrible habits because I don’t spend
enough enough time with it and I kind of
got I wrote some unit tests here but it
also means that we are not quite getting
to the meat of it I wanted to show some
some function composition and we are
just not doing that we deliver the
endpoint let’s see okay let’s see the
logs give me give me some more
information
oops username batch ID and the reason
think that this ops seemed to they
seemed really fine actually so that’s
interesting so look at this assigned
batch maybe I there’s some problem in
assignment maybe I broke it yesterday
something oh we are actually not passing
passing this in that shouldn’t I don’t
feel that that should matter though
we’re like what I’m going getting at
here is that reason it’s not actually
being being passed in to make a sign
okay actually see what the problem is
here oh we’re actually doing some
couples here functional position here
but we’re starting with one of the worst
things with function composition and
that is that it’s horribly hard to debug
because that is not the fault of
function composition per se it’s just a
photo of lambda I mean this Ram de you
could have made this into a lot nicer
air match message but what is happening
see see here that this I reflected this
yesterday and that is why it broke and I
didn’t test it properly pipe P is a
function in RAM de that creates a
it’s going to create return a new
function that will take whatever value
it gets passed to it and then it’s going
to pass that value to the first function
here make body so whenever we call the
assign badge function it’s going to call
body with these two arguments and it’s
from that function and pass it on to the
next function and so on that is what PI
does but this is PI P and PI P does
exactly this
thing except that it expects every
function to return the promise and that
is what I missed here so what I need to
do is just do this promise don’t resolve
Blatt a sign badge is not under test yet
might and that later but for now let’s
focus on solving the problem bum bum bum
bum promise fixed make a sign batch this
also means that a lot of people have not
been receiving their their badges of
Awesome because this has failed I need
to do some repair job later but that’s
cool it’s not a problem pushing so we
still don’t have a reason but I expect
this to work now
he said famous last words
yes 200 it works so let’s have a look at
the API test I should now have gotten
the interruption batch I did but it’s
it’s not actually linking to anything
and that is because it’s lacking lacking
a reason we’re going to assure that a
pass in reason we passed that you get
push rocket master so now I’m going to
hey badges wait
remove the API test match while I’m at
it revoke the badge all right scary
terminology and I think that I can just
now go to the deployed yet it has
deployed I think I can just read liver
this immediately koplow does it work
does it work does it work introduced
look at this
granted introduce yourself works
fantastic okay so this works now however
we haven’t done much functioned
composition which was what I promised
you
in this episode see if we can have a
look at the reason why we haven’t done
much composition is because there’s
already I’ve already done a lot of
function composition in this in this
project and the function that we just
created handle post created like there’s
not a lot of stuff going on in it so
there’s there’s no white anything we can
do to compose it I mean we already are
already using this assigned batch inside
of it so we in one way we are composing
functions functions already perhaps I’m
in the parking statement I think that we
might just go into a sign patch and
unravel this this function composition
here to give you a sense of what what is
happening so we have the make body mmm
okay let’s do this I’m going to rewrite
this you without using the the piping
function let’s let’s just do that let me
close this one and close this one so
first of all what this does remember is
that it creates a function so what we
and I’m going to comment this out to
remember that this is what we are
working with the first thing is that we
what we’re gonna do is we’re gonna make
a body boat and then right we are we
also need the arguments here are the
options and then we are going to post
this as JSON to a bit of dope dope dope
and we’re going to use this discourse
API euro and we’re going to pass in the
body so this is actually also an example
of function composition here this thing
is another factory function with which
creates a a function so what we do here
is actually pose as Jason to use or bad
just end point creating this function
then because this will be a a response
also and we do all right let me show you
what error unless ok looks like inside
again we looked that before but what it
does it’s it’s a function that takes a
response and it checks the status and a
code on that object and if so if that’s
not 200 it throws an error so what we
actually could do here yes to reuse that
like that and then we can actually just
return this you can actually just return
this but I’m going to write that out to
make it a little bit clearer what is
happening because this returns a promise
or it actually returns a response
promise promise that will resolve to a
response object so when the response
promise resolves then we do the error
lesson okay and then we we return
because this and the reason why we
return like this is that there is no we
are not really interested in what the
and it data from the response because we
are posting data to the endpoint here so
as you see her like this is kind of I
must say that now that I write it out
like this when I have the compare
functions compose quite nicely might be
that this pipe function doesn’t really
add much or at least it’s adds a little
bit because this looks pretty cool it
looks it’s very focused on what it does
it makes a makes a body for the post
request and then it posts that as Jason
to the discourse your eye user badges of
Jason and then error unless okay and it
so this is what is called point free or
tacit programming it’s nice because it’s
focused on what is what the code intends
to do rather than like assigning
variables back and forth it’s it’s
readable in a nice weight however pipe P
is as you saw it was hard for me to
debug because the error messages of
these composed functions becomes
sometimes just horrible and let’s try to
see if we can compose things with
promises without using this this pipe P
just fun so we have this this response
body that we’re creating or sorry the
request body let’s try this instead
and so this is the body and then we do
we use this BAM that’s pretty cool
Hey okay that’s pretty cool actually
that’s actually a lot a lot nicer I just
thought it was so cool to use this
random thing but ah when you do promises
you can actually chain them up really
really nicely that’s pretty cool it’s a
little bit annoying that this is not
named we could do something like call
this like toast body which would and do
like that perhaps does it make it better
hmm I don’t know I don’t know actually I
think it was really like this because it
would allow me to just you do this a
simple one-liner arrow functions I can
just do this and then do declare this as
single line arrow functions and yes have
like that that’s pretty that’s pretty
spiffy so this is exactly the same it
just we have the body here if we resolve
that as a promise because that’s what
promise dr. song does and then we post
that as Jason to discourse API URI used
to badgerstour Jason and then we call an
error unless it’s okay and if it’s okay
we just
returning the response it’s pretty
pretty nice and the reason why we can
why this works so so nicely is that
these things are are very composable
functions so error unless okay it’s very
easy to stuff into a den because what it
does is that it it’s just a simple
function that takes one argument it
errors if it’s if it’s not something
otherwise it returns or chance responds
if we use it inside of a promise we
actually don’t have to do this but I had
to add that while I was using the the
pipe operation I don’t think I can
remove it because I’m using air unless
m’kay in other places that uses pipe II
still but looking at this this is this
is a distinct improvement over over this
this is actually way less complicated
and convoluted and I
I also get rid of over dependency here
I don’t need Ram de inside of this
function also you see here like this is
also a great example of a function
components sorry this is also a great
example of function composition the
discourse API URI let me remind you what
that does it just creates an a URI from
a full URI from just the path so if I
have just this path what it will do it
it will weld on the domain in front for
forum and all that stuff and it will it
will also weld on the API key and and
query string sorry the API key and
username it needs as a as a query string
on the on the passive will transform the
path to full API URL so that’s what that
returns
and then post us Jason to post ask Jason
to what that will do is that it’s going
to oh this is carrying a lot of carrying
here so this is just a dependency
injection that we have on the top level
but then because we need because this
function needs fetch but then what it
does is that it takes a URI again if you
look here this is the URI then oh sorry
oh I’m jumping around confusing you
sorry sorry about that corrected for
such poor situation and then it creates
it this will return another function
which is the actual function that is
prepped with the URI and this function
is now is this function that oh I’m
ready to post to this specific URI and
all I need from you is a body and when
it gets a body it does the fetch and
does the post posting the JSON and it
puts the body it’s pretty nice so maybe
you like I’m gonna just extract this to
make it more obvious what it does so
this creates a new function it’s a new
function post as Jason to badges see so
this will now actually this is a
that will accept this so you can
actually you could do this as well so it
kind of if I wanted to rewrite this in
more another style I could do could do
this cause it’s Jason two badges and
this is not too bad either actually I
but it’s not quite you see that it’s not
in the natural order we just we create
the function first here and then assign
it we could we could do we could do this
we could actually inline it do this
that’s that’s weird
so posts Jason to discourse API URL and
then we would pass in the body and it’s
it’s okay it’s not absolutely dreadful
but it’s a bit convoluted and I think
that something the original version
where we just did this is pretty slick
pretty slick yeah it’s to me this is
very readable as a chain I hope this to
YouTube maybe and I see also again as
you see here this is using currying so
the first first time you first time you
call this function so to speak you call
with the dependencies that creates
another function which is the actual
function that returns the that accepts
the arguments and but it has been
prepped with those dependencies the
process Jason too is now because of the
power of closures available available
here so if I go back to index show you
how that works
we’re here’s the assigned batch so we
just require the assigned batch and then
we pass passing the dependencies and
that will give us the actual assigned
batch function so you could view this as
let make a sign badge
whap require this is not forsake on a
function composition this is just
inversion of control in a functional
style but it gives you gives you a sense
Mike I hope it helps to see these things
where I just pass functions around and
doing all this kind of carrying and
stuff it might help you to see how this
all falls together and how you it makes
it easier to combine and compose
functions maybe not maybe I’m just too
tired at this point and just involved in
my own functional I don’t know
what do you think write a comment down
below if you enjoyed or didn’t enjoy
this this turned out to be a long one oh
yeah I thought I would be able to pull
this off quickly but no anyway I am
going to sign off now you have just
watched an episode of fun fun function I
release this every Monday morning away
200 GMT they are not usually this long
if you like this you might also like
this video that Google’s machine
learning thinks is good for you if you
really like this please do consider
becoming a patreon by clicking there
it’s a great explanation of why you
should I am mpj until next Monday morning stay curious