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
Letβs create a list of ideas and display them in our template. You will explore using the Model in our View that was passed to you from your Controller. MVC in action!
Learn more:
- Model View Controller - MVC - Pattern
- Post/Redirect/Get - PRG - Pattern
- Weβve got a course in the works on Functional Programming. Check back soon! For now, check out the official Oracle tutorial on Streams
The updated design from our design team!
body{
background-color: #eaeaea;
font-family: Arial;
}
a{
color: #2c89ba;
text-decoration: none;
}
a:hover{
color: #174963;
text-decoration: underline;
}
ul{
padding: 0;
}
li{
border-bottom: 1px solid #eaeaea;
list-style: none;
margin-bottom: 10px;
padding-bottom: 10px;
}
li:last-child{
border: 0;
margin: 0;
padding: 0;
}
.page{
background-color: #fff;
border-radius: 5px;
margin: 40px auto;
padding: 20px 40px 40px 40px;
width: 600px;
}
input{
border-radius: 5px;
border: 1px solid #ccc;
padding: 10px;
}
button{
background-color: #2c89ba;
border: none;
border-radius: 5px;
color: #fff;
padding: 10px;
}
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
All right, let's get into
the meat of our application.
0:00
Let's allow students who we
know to submit ideas, and
0:03
then we'll display them in a list.
0:06
How are we gonna make sure
that we know the student?
0:10
I know, let's expose a link
in our if statement that
0:13
checks if we know their username.
0:16
Okay, so let's start out by
opening up our index.hbs page.
0:19
So that's this guy here, index.hbs.
0:23
And I'm going to get rid of this
TODO because we TO-DID that.
0:26
And so inside the if block here,
we want to add a hyperlink and
0:30
a hyperlink will do that
using an anchor tag.
0:35
So let's make a new paragraph here,
and we'll say View and if I do a and
0:39
then I do a Tab, it's gonna build out and
0:43
that href there is the reference
of where we want it to go.
0:46
So we want it to go to /ideas,
which we havent built yet, but we will.
0:50
And we'll make it say
View all course ideas.
0:55
And that makes that a link, right?
0:59
So when you click all course ideas,
it will make a get request to /ideas.
1:01
So we better catch that, right?
1:07
So let's flip over back to main.Java.
1:08
Let's add a new get, and
we'll say get ideas.
1:13
And that of course gets our request and
response object route.
1:19
We know it's gonna be a multi-liner.
1:24
And we know that it's gonna take
the new HandlebarsTemplateEngine.
1:27
Okay.
1:35
Why don't we just pop our ideas
into the model context, right?
1:37
Now obviously at first there
won't be any but that's okay.
1:42
Let's do it.
1:45
So we'll make a new model.
1:46
[BLANK] Yeah,
1:48
that of course is a HashMap.
1:51
It's getting repetitive, isn't it?
1:57
Sure wish that that auto-completed.
2:01
There's probably a way to do that.
2:03
Okay, so inside the model, let's put
our ideas, a collection of ideas.
2:06
And now we have access to
our data access object.
2:13
And remember, we made one called findAll,
2:17
and our implementation
returns a copy of the list.
2:20
Cool.
2:23
Sorry, we don't want String String on this
one, we actually want String object.
2:24
Okay, and
we're going to return new ModelAndView,
2:32
and we're gonna return the model and
2:36
we're gonna have that go to our
ideas page that doesn't yet exist.
2:39
So, let's go make that.
2:45
So, we'll make a new ideas.hbs file.
2:47
Okay, and we want to first say
what we're gonna inherit from.
2:53
Let's inherit from base.hbs.
2:57
Now that that's out of the way we
can add our new partial at the top.
3:00
We want this to be the partial for
content.
3:06
Great.
3:10
Okay, so we know that this is the idea
page so that's a good heading, right?
3:11
So, let's say Current Ideas.
3:15
So in HTML when you want to display
a list you actually have a few options.
3:20
So one of the most obvious ones to
use first is an unordered list,
3:24
and that's a ul.
3:28
So you type ul and each one of those has
a thing called an li which is a list item.
3:29
So what we want to do is we want to
loop through each of the ideas and
3:35
make a list item.
3:39
So in order to do that Handle Bars
has a really nice block helper and
3:40
it's called each.
3:44
You can kind of imagine this
as doing a for each loop.
3:45
So we're gonna say, #each, and
then you loop on the object.
3:48
Now remember when we pushed
ideas into the context, so
3:52
we're gonna loop through each idea.
3:55
So basically this is saying for
each idea in ideas.
3:59
And we'll add a new li.
4:03
Or list item for each of those ideas and
now this is a little bit different.
4:06
Inside this each loop,
it's the block scope is against the idea.
4:10
So actually all we want to do here
is we want to show the title, right?
4:16
So we're going to show
the title of the idea.
4:21
Now wait a second,
how does it know about the word title?
4:25
The course idea object, if we take a look
at that, it only has getTitle, right?
4:28
This is a private thing so it can't see
that, so it only sees this getTitle.
4:34
So the handlebars.java implementation
understands POJO, or
4:37
plain old java object syntax.
4:42
So it knows that it can call
the getTitle method on our object.
4:45
It's pretty cool, right?
4:48
So, we didn't need to write getTitle here.
4:50
We just wrote title and it pulled it out.
4:53
Okay, so let's walk that one more time.
4:58
So, we passed in a list of course
ideas into our model context,
5:01
right, for model and view.
5:05
And then, there's a block helper and
it's called each.
5:07
It works with each item in this list.
5:12
For each of those items,
it puts it into this block's scope.
5:16
In here, this block's scope is that item.
5:21
And it pushed in a course idea object,
which has a method called getTitle,
5:25
and it can be accessed here
by not putting the get prefix.
5:31
Make sense?
5:34
Okay.
5:36
So now after that each, let's go ahead and
let's add a form to add a new one.
5:37
So, let's make it post to the same page,
to ideas, right?
5:44
But we want it to post, right?
5:50
Cuz we're adding information.
5:52
Okay.
5:55
Inside this form let's
5:57
have a field called title.
6:01
Let's make the placeholder
say "What's your idea?
6:06
And we're gonna name that title so
6:12
when it comes across it will
be title in the query string.
6:14
All right.
6:18
And then let's make
a button that says Suggest.
6:19
So clicking that button will submit
this form via post to ideas.
6:27
So we better go catch that, right?
6:33
So let's go back to Main,
and we already have one for
6:36
ideas here, but we can also do
a post version to the same URI.
6:41
So we'll do req and res.
6:49
Okay, so let's pull the title
from the form submission.
6:57
So we wanna get a title out.
6:59
So the title is going
7:01
to be req.queryParams.
7:06
And we named that field "title".
7:13
Great, okay, so now we have the title,
and let's make a new course idea.
7:15
We'll use the title and then we'll
pull the username from the cookie.
7:21
Okay, so we'll say new
7:26
CourseIdea = new CourseIdea.
7:30
No, not course idea.
7:36
Let's go ahead and say that it's that,
and we want to pass on the title and
7:37
it takes a title and it takes a username.
7:43
So we'll pull that from the cookie.
7:49
It's a little interesting, right?
7:53
We're binding our implementation detail
to the fact that it's using a cookie.
7:55
What if we wanted to change that later?
7:59
What I'm gonna do,
I'm gonna leave a TODO here,
8:01
because that feels a little
awkward doesn't it?
8:02
It feels like the only way that we
know who's logged in is by a cookie.
8:04
We don't wanna expect that, so let's leave
it the TODO here and csd is my initials.
8:09
So, this username is tied to
the cookie implementation.
8:14
That's not good stuff.
8:20
We wanna fix that.
8:21
Okay, and our data access objects
exposed a method that lets us add.
8:23
We should probably use it, right?
8:27
So, the data access
object add(courseIdea).
8:28
Now we could show a page that says it was
added but that seems kinda silly, right?
8:35
What should happen is that the user should
just see their idea on the list, right?
8:40
But we can do this.
8:43
Why don't we just refresh the ideas
page and it should just show up, right?
8:45
Because we added it and
before in the get we lifted them all so
8:49
it should just show up.
8:51
So this is known as redirection.
8:53
What we'll do is we'll redirect
the client to the Ideas page
8:55
which will hit our get route here.
9:00
Cool?
9:03
So let's add it.
9:04
So, on the response there is a method
called redirect and you pass in the URI.
9:05
So, redirect it, it's gonna do a get,
so it's gonna do a get there.
9:12
And we have to return something, so
the pattern is that you return null.
9:16
Okay, what do you say we give that a go?
9:22
Let's do it.
9:24
So I'm going to run my server,
restart yours if yours is running,
9:25
mine had stopped.
9:30
Okay, and I'm gonna flip over here,
go to localhost.
9:35
I am currently logged in, so
we saw that in the if statement.
9:41
We can stop that.
9:45
Let's bring that up and
let's take a look at the resources.
9:46
We'll wipe this cookie.
9:51
Let's make sure that we don't
see the view all course ideas.
9:55
Awesome.
9:57
Okay, so do, now that we know who's there.
9:59
This page is kind of ugly,
we need to get rid of this.
10:06
Now we can do this.
10:09
We can click on View all course ideas.
10:10
What's your idea?
10:12
I think that we should have
one on how to test spark.
10:13
So we should do Spark Testing.
10:17
Now I had to type that in before,
that's why that showed up there.
10:18
I'm gonna click Suggest.
10:20
Whoa, look at that.
10:23
It just showed up.
10:24
So again, what happens is we posted and
10:26
then the response added it to the list and
then it redirected to ideas.
10:30
Now, the browser knows how to
handle what a redirect is.
10:35
It tells the browser to
make a new get request.
10:38
So, really, what happened here was
two request response loops, right?
10:40
So, I put in the idea.
10:44
So, let's say that I
wanted to do a course on
10:45
CSS Basics and we click Suggest.
10:48
So that's gonna do a post.
10:57
And then it's sending the new get, right?
10:59
So what this is known as is
the post-redirect get pattern or PRG.
11:02
More in the teacher's notes.
11:07
So remember, this simple course idea,
Data Access Objects, we built here,
11:09
it only exists in memory.
11:13
So if we were to reboot,
it would just go away.
11:15
But many others at this time could hit
this site, and also add their ideas.
11:18
One second here,
I just got a ping on my messenger.
11:22
[LAUGH] Just like I thought, a designer
coworker friend of mine walked by my desk,
11:24
and saw what we were doing, and sent me a
message saying, dude, what is it, the 90s?
11:30
Here's some CSS in a better wrapper.
11:34
[LAUGH] I love working here.
11:35
All right, so he gave me some CSS.
11:37
So I'm gonna go ahead, I'm gonna grab
the CSS I put in the teacher's notes.
11:39
So, if you wanna copy it to your
clipboard, which I'm doing right now,
11:43
and if we paste that in our main CSS
11:49
file and go ahead and save that.
11:54
It's a lot of stuff there.
11:59
I'm trusting him because
I trust my co-workers.
12:01
I'm gonna flip over here to my
12:03
base page cuz he wants us to add
a new wrapper around our page.
12:09
And because we have a page
wrapper we can do that.
12:15
So I'm gonna make a new div
which is like a divider or
12:17
division a section like thing.
12:19
So we're gonna say class = page.
12:22
And that div is gonna span all
the way across our content.
12:29
All right.
12:32
So, this is what Sully,
my designer friend, wanted us to do,
12:35
my coworker, so let's take a look.
12:40
Let's go ahead and refresh our page.
12:43
Wow, nice.
12:47
Look at our ideas.
12:49
Much better.
12:52
Thank you for
bringing us into the current century.
12:54
>> Great job getting that
list of ideas displayed and
12:58
adding a form that updates our data.
13:00
This is really starting to come together.
13:02
One thing that jumped out to me,
is that we blocked unknown users, but
13:05
only by not showing them
the View All Ideas link.
13:09
But the way that the Internet works,
anyone can pass a URL around, so
13:13
just keeping that link
hidden behind an If block
13:17
isn't really the best
way to protect a page.
13:20
You know,
now that we learned that redirect trick,
13:23
wouldn't it be cool if we didn't
have the right credentials,
13:26
if we didn't have their username,
if we could block them from continuing?
13:29
Let's do just that after this break.
13:33
I was thinking, do you think you can
remove that silly page after sign-in and
13:36
just have it redirect to the home page
after they submit their username?
13:40
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up