Press "Enter" to skip to content

Let’s code with function composition – Fun Fun Function


good Monday morning today we’re going to

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

Please follow and like us: