Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
What do you do when your micro-framework doesn't provide a feature you need? You build it!
Flash message CSS
#flash-message{
background-color: #2c89ba;
border-radius: 5px;
color: #fff;
display: block;
font-size: 14px;
padding: 10px 20px;
}
Explore
One way you to get around the duplication is by taking advantage of the request.attributes and creating a model object in a global before filter. That would allow you to do whatever injecting of the model that was common to all requests. In the controller you just then pull out request.attributes[“model”] and add specific information, but it would have the flash message.
Okay, so
now let's develop our flash messages.
0:00
So again,
not having all the tools at your disposal
0:04
doesn't mean that we can't build our own.
0:07
So one thing we haven't talked about yet,
and
0:09
we're gonna lean on this pretty heavy,
are these things called sessions.
0:10
So web sessions are a key value data store
that are available in most frameworks.
0:15
They're specific to the client or
the website and
0:19
it's kinda like a pocket that
you can stuff things into.
0:21
Spark offers one and
you can access it right off the request.
0:25
So the way that Spark uniquely
identifies a session,
0:28
it does it by sending out
a uniquely identified cookie.
0:32
We'll take a look at that here in a bit.
0:34
But the server then uses that
cookie to maintain a data store for
0:37
each client who asks for
one of these sessions or packets.
0:41
Let's start by using it and
I'll show you how it works.
0:44
Let's build a simple way to
set a single flash message.
0:47
So first let's attack
the messaging around voting.
0:51
So add voter, we made it so
that it returns a boolean, but
0:54
we're not doing anything here with it yet,
so let's catch it.
0:57
So let's say boolean added, and let's let
them know that their vote counted, right?
0:59
Otherwise it's kinda confusing.
1:04
You vote and get redirected and
might see it there in the list, but
1:05
let's make sure that they see it.
1:09
So we'll say if added, and
we'll call a message that we have
1:10
not written yet, so
we'll say set flash message.
1:15
Thanks for your vote.
1:21
Now what's nice about writing
the message name before it exist is,
1:27
IntelliJ is gonna build this for us.
1:31
So we'll say,
create method set flash message.
1:33
And now it knew that we are in
the static context, right?
1:36
And it knew that it didn't return anything
cuz we didn't ask it to return anything.
1:41
And it popped in the request and
the string for us.
1:44
I'm gonna clean this up a little bit here.
1:46
It's not quite right.
1:48
So we're gonna say
the string is the message.
1:49
The request has a method
named session on it.
1:53
So if we say req.session and
you see there, there's two options.
1:57
We have one here that says create or
something with no parameters.
2:04
So, by default, it will create one.
2:10
And this is okay in this case cuz
we're saying set the flash method,
2:13
but we don't want it to always create it.
2:17
So, when we go to check this in a bit
we wanna remember that we don't wanna
2:19
create a session if we don't need it,
right?
2:23
Because that's just expensive and
wasteful.
2:24
But we're gonna set a message, and
2:27
if we don't have one of these web sessions
to do, we need to have it right, so.
2:28
So we're gonna say req that session and
2:33
the way you set key values is
with a thing called attribute.
2:36
So we're gonna say attribute and attribute
we want is we wanna set a flash message.
2:39
So this is the key the name and
2:45
there we're gonna pass in what came
across which is message there.
2:47
We're probably gonna use this string
here a lot to get them out as well.
2:53
So this is a place where we should store
it once and then use it many times.
2:57
So let's go ahead, and I'm gonna do,
I'm just gonna say flash message key.
3:01
And this is a good place for a constant.
3:06
And remember those are all capitals.
3:08
So we'll say FLASH_MESSAGE_KEY.
3:09
And of course that's not defined yet, but
3:11
let's go ahead and
have IntelliJ help us out.
3:13
So we'll create a constant
field FLASH_MESSAGE_KEY.
3:15
Exactly what we want.
3:18
So there it is,
3:20
it blew out java.lang.String
completely for some reason.
3:21
We don't need that.
3:24
FLASH_MESSAGE_KEY.
3:26
And we're gonna set to be flash message.
3:27
We could then change that to
whatever we want in the future,
3:31
should that have some sort
of namespace closure.
3:34
But this is all up here and
3:36
remember it's static because we're
accessing inside of a static method.
3:37
Awesome.
3:41
So, what good is our setter if
we don't have a getter, right?
3:42
So let's go ahead and
let's add our getter.
3:47
Now this one is gonna be
a little bit trickier.
3:50
So it's also gonna be private.
3:53
It's static,
cuz we're gonna access from inside.
3:55
I'm gonna say getFlashMessage.
3:57
It's gonna require a request object,
4:03
because that's how we're
gonna get to the session.
4:05
Okay so like I was saying before one
thing I wanna make sure is that we
4:10
don't create these sessions
if we're not gonna use them.
4:14
You don't wanna check and
accidentally create one.
4:17
Totally wasteful.
4:19
So what you can do is pass
a false through there.
4:21
So if you say req.session and
4:23
you pass a false which this should
just create if it doesn't exist.
4:26
So we're gonna say false.
4:30
If that doesn't exist,
then there's no flash message to get,
4:32
so we should just return null, right?
4:37
So we're gonna shortcut this function.
4:41
There's no need to keep going.
4:43
And I'm sorry.
It's not void.
4:45
We wanna return a string.
4:46
Okay.
4:50
So, if the session already exists,
maybe somebody else created it.
4:50
So we wanna make sure that our key exists,
okay?
4:55
So we're gonna say if req.session, and
now we know that it already exists.
4:58
Because if it did,
the session wouldn't [INAUDIBLE].
5:05
So if req.session.attributes,
this is a way you can get all of them,
5:08
contains FLASH_MESSAGE_KEY.
5:11
Okay, so what we're gonna say
here is actually if it doesn't
5:17
let's get out too, we return null.
5:21
And then finally, if it does exist,
we can pop it out.
5:28
Now here's the thing, we need the cast.
5:32
Remember we needed a type cast
because what goes in there are, it's,
5:34
the key is a string but
the value is an object.
5:39
So we're going to get the session,
we know that it exists.
5:43
We're going to pull out the attribute.
5:46
FLASH_MESSAGE_KEY.
5:47
Cool.
5:51
So now we can get and set our messages,
let's make a way to display them.
5:52
Now this really could be on any page, so
5:57
first let's set up our base.hbs
with a flash message area.
5:58
So let's go into base and
6:03
right in here inside the page, let's
make it the first thing inside the page.
6:07
So, one thing that we haven't done yet
is we have not pushed a model in.
6:11
So this could be on any page so
let's go ahead and
6:17
let's say any model that has
a thing called flash message.
6:19
We will just write out p and
6:25
I'm going to give it an HTML id, so
we can really specifically target this.
6:29
So we'll say flash-message and
6:34
we will write out here the value
of flashMessage should it exist.
6:37
Now one thing that's really nice about
Handlebars is see that if there.
6:41
This if even if it doesn't exist,
if this doesn't exist,
6:46
it somehow is going to say it's
okay it doesn't exist in the model,
6:49
I don't care that you're talking
about a variable that doesn't exist.
6:54
In Java that would kinda throw up.
6:57
It would say that this doesn't work,
this can't compile,
6:58
I don't know what you're talking about.
7:01
But here in Handlebars it's kinda wrapped
in a notion of something that's kinda
7:02
falsey, right?
7:07
Okay, so Sully is always thinking ahead,
our designer friend.
7:09
He sent me some CSS already.
7:13
He said, if you ever wanna show them some
flash messages, why don't you use this?
7:14
Which is great because I would
not know how to style this or
7:17
even think about styling it, so
let's pop into our main CSS and
7:21
I'm just gonna add this
here at the bottom.
7:26
We'll add this flash message.
7:28
Cool.
Thank you, Sully, once again.
7:31
He's so good.
7:34
So let's go show this
on our list of ideas.
7:36
When we're showing the ideas here,
we're now going to add to our model.
7:40
We'll say model.put and
let's put in a flashMessage,
7:43
right, that was the model
variable that we're looking for.
7:48
And we'll say getFlashMessage and
we'll pass on the request.
7:50
Cool, and that therefore,
if it exists it will push it across.
7:56
If not, it will be null and
it will not show our flashMessage.
7:59
So let's go ahead and
let's open this up and
8:02
reboot the server and
I'm gonna come over and
8:07
let's refresh the page here
let's get back to the ideas list
8:13
let's put in Spark Testing and
suggest that.
8:22
Okay, now let's go ahead and
look first at these resources.
8:27
And we'll look at our cookies.
8:30
And you'll see that I only have
this username of myself here.
8:34
But when I vote, you should create
the session and set that message
8:38
that we successfully voted into it, which
will therefore, first create a session.
8:44
Okay, so let's click vote.
8:48
Boom.
Here's our flash message, and
8:50
look, here is our cookie, and
8:52
this is the way that we're being
uniquely identified from Spark.
8:54
So the name of it is this, and this is
the value, some long value over there,
8:57
but that's how it's knowing what
session we're talking about.
9:03
So, we have a session.
9:08
So, let's see,
if I refresh this page, hmm.
9:10
That message stays there because
the flash message is there.
9:16
One thing most flash messaging
systems do is make sure that
9:21
after the user has seen the message once,
they don't see it again.
9:24
So, let's make ours a little bit smarter.
9:27
We wanna leave the gitting in place
in case they don't want this specific
9:28
functionality but, in this case,
I think it makes sense.
9:32
So, let's go over,
back to our main method.
9:34
And let's add,
let's add a new method called
9:37
captureFlashMessage, it
will be much like this.
9:41
So I'm gonna copy it and instead of
get let's say captureFlashMessage.
9:49
And let's pull that out,
let's pull the message up,
9:59
string message equals get flash
message and pass on the request.
10:02
Okay, so if the message isn't empty,
if we've got something, right?
10:07
Then we have a session, so
we should remove that key completely.
10:15
So the way that you do that
is remove attribute, and
10:20
we're gonna remove the FLASH_MESSAGE_KEY.
10:23
So therefore,
this is going to see if it exists,
10:25
if it does, we are going to get rid of it.
10:27
You're going to pop that
off of the session.
10:33
Cool.
10:36
So now we come back to where
we were using getFlashMessage.
10:37
Which is in our listing of our ideas
up here, somewhere, here it is,
10:44
so, we're saying getFlashMessage,
we're going to say captureFlashMessage.
10:52
So this time it will show it once,
and then it will disappear.
10:56
So let's add an else to where
that voter call was, right?
10:59
So else, so it wasn't added, so
we're gonna say setFlashMessage,
11:04
and we'll say request, you already voted.
11:11
Now see how easy it was now that we have
all the functionality in place to add
11:16
a brand new message, it's pretty easy now.
11:20
So while we're here, let's go ahead and
let's check our to do's.
11:23
So we have this one about sending
a message about a redirect somehow.
11:26
So before they try to get to the ideas
page, if they are not logged in,
11:29
we redirect them.
11:34
So let's go ahead and let's get rid of
that to do and let's add a flash message.
11:35
We'll say whoops, please sign
11:44
in first and it will redirect.
11:49
Here's the other thing.
11:57
For the splash page,
we need to make sure that we also
11:58
capture the flash messages and
add them to the model.
12:01
This is starting to feel
a little duplicated isn't it.
12:05
Check the teacher's notes if you're
interested in how we might be able to
12:09
wrap this up.
12:12
So it's a captureFlashMessage(req).
12:15
So for
now it's in only two of these calls but
12:22
if we do this we're gonna
have to do this everywhere.
12:24
So you wanna make some
way to make that generic,
12:27
but again check the teacher's notes.
12:29
So let's go ahead and let's pop over and
we'll wipe both of our cookies away.
12:31
Let's get rid of the username too.
12:39
We will try to refresh the ideas page,
okay?
12:41
So what's gonna happen is it should
tell us that we need to log in.
12:46
So we're redirected, face palm,
I forgot to restart the server.
12:49
Do not forget to restart the server.
12:56
So frustrating, right?
12:59
Okay.
13:01
What did I do wrong?
13:05
So it says,
I forgot to pass in the request.
13:07
Okay, so let's run that again.
13:13
We're not logged in,
we're going to go to /ideas.
13:16
Now this is going to
create a flash message for
13:19
us cause or create a session for us
because it's going to set a flash message.
13:21
There.
So it says whoops, please sign in first.
13:26
Now that redirect makes more sense,
doesn't it?
13:27
And there is out session
idea that got created.
13:30
So now let's log in and
if we go to view all course ideas.
13:32
And we'll say Spark Testing.
13:40
I'll vote for it once and
it'll say, thanks for your vote.
13:45
And if I come and I refresh this page,
see how the message has gone away.
13:47
But if I try to vote again,
it'll say, you already voted.
13:54
Awesome.
13:57
That was an excellent micro-implementation
of flash messages using web sessions.
13:59
Wow.
You built that
14:04
messaging system in a flash!
14:05
You need to sign up for Treehouse in order to download course files.
Sign up