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
This is how I added the Detail page to our application? How did you do?
Directions from previous step
- Add a new page that responds to
/ideas/:slug/
. The controller should get the model by the slug passed in the url and pass it as the model for the template created in step 2.
- Add a new template for the idea detail page. Make it inherit from our base template.
- The content of the new idea detail page should list everyone who voted. You might need a new keyword.
- Add a form that allows voting for this specific idea. Route it to the existing vote route.
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
So if you haven't done it yet, please try
to do what is described in the teachers'
0:00
notes on this video, but
this is the solution how I solved.
0:05
How'd you do?
0:08
First, I exposed a property on our
CourseIdea model that returns the voters.
0:10
Now, since I am making a copy of this set
of voters anyway, I decided to use a list.
0:14
No need to show them how the users of
this API, how I'm keeping things unique.
0:21
So I'm just gonna give a list
just like everything else.
0:27
Everything else out of
here will return a list.
0:30
So and we're gonna get the voters.
0:32
It's asking if it's a java.util.List.
0:36
It indeed is.
0:38
And I am gonna do the same trick that
we did before where I'm gonna make
0:40
an ArrayList.
0:44
And I am going to have that
take the set of voters and
0:46
make a brand new list so it's a copy.
0:50
So anytime they try to mutate that, it
won't actually mutate the original voters.
0:54
And next, I added a route to our
main method, and main over here.
0:59
That's a get.
1:04
So we wanted to get where the ideas slug,
so
1:05
we want them to be able to go
ideas slash whatever the slug was,
1:09
and that's gonna give us a request and
a response.
1:15
And inside of the body of our method here,
1:22
we are going to have a new
Map that is a String and
1:26
Object key and value of a new HashMap.
1:32
I don't know why that
doesn't auto-complete.
1:42
If somebody could figure that out and
let everybody know,
1:44
I'm sure they'd love you for it.
1:46
So we're gonna do model.put.
1:48
I'm gonna put in there, put in idea.
1:50
We're gonna do find
1:53
findBySlug(req.params("slug")).
1:56
And then,
we're going to return new ModelAndView.
2:07
And we're gonna pass it in our model, and
2:13
we're gonna give it a new template
name that we have not yet created.
2:16
I'm gonna call it idea.hbs because it's a
singular idea as opposed to the ideas page
2:21
that we had.
2:26
And of course that's
the HandleBarsTemplateEngine there.
2:27
So let's go make our idea.hbs file.
2:31
So New> File> idea.hbs.
2:36
And we are going to extend base.
2:40
I always like to put that first here.
2:46
Next, we are going to override
the partial for content.
2:52
And we are gonna make a heading of
3:02
idea.title, let's wrap that.
3:08
So remember, I passed idea in.
3:16
And so, idea has properties.
3:18
So it's doing idea.get title.
3:22
And then, we're gonna do another one here.
3:24
We'll say idea.voteCount.
3:26
So this is an h2, so
it's like the second header, Voters,
3:29
and four of that will make
a new unordered list,
3:36
and I am going to loop
each of these idea.voters.
3:42
We're just gonna use our get voters.
3:48
So I looked up in the documentation
on Handlebars.java of how to access
3:50
the current item.
3:55
Now, since voters was just a string and
not an object of ours,
3:57
what you can do is you can
just use this as the keyword.
4:02
So we're gonna say, <li>{{ this }}.
4:05
That is how you reference
the current scope.
4:08
So the current scope in
there is this string.
4:11
Which is the username, so it's this.
4:14
Cool.
4:16
And then, I also added a form
that's gonna go to the same place.
4:17
So we're gonna say ideas.
4:21
And we want that to go
to the {{ ideas.slug }}.
4:22
We want that to be able to vote, and
4:30
we'll add a button for voting.
4:35
And we don't wanna
forget that it's a post.
4:38
So we wanna do method = "post">.
4:42
You know what, while we're in here,
why don't we also change the title, so
4:47
we'll do {{#partial "title" }}.
4:51
Two partials there accidentally.
4:59
I forgot to close that out, partial title.
5:02
And we want the title here to be,
5:05
{{ idea.title }}.
5:10
So that will change the page title
to be whatever the course idea is.
5:14
Guess we could prefix it
with something like this.
5:19
And then, made the ideas.hbs page,
5:23
you wanna make these all links,
we wanna make sure that anything
5:27
that has this title is showing
up here that it's a link so.
5:30
Wanna do an a tab, and
we're gonna go to ideas.
5:34
And this one, we have the idea
in context so we can do vote.
5:39
Or we wanna go not vote,
we wanna go right to the page,
5:46
to the new detail page that we made.
5:49
So that links to the detail page.
5:52
Awesome.
5:56
And I think that should do it.
5:58
Let's restart our server and give it a go.
6:00
Let's see what happens.
6:02
So let's log in.
6:07
So let's do Spark Testing.
6:14
Let's make, you know what we should do?
6:18
We should make a REST API with spark.
6:20
How about the Ninja Framework.
6:23
So what happens if we come in here,
there's zero voters,
6:29
what happens if I come in and I vote?
6:32
There we go, there's one voter, and
if I choose Vote, uh-oh, ideas//vote.
6:35
So we're missing that page.
6:41
So for some reason, the slug that I wrote
out, on this vote page here is wrong.
6:44
Let's go, and
see if we can't figure out why that is.
6:49
So on the idea page in the vote,
the partial,
6:53
I said ideas.slug,
it's not ideas, it's idea.slug.
6:58
Restart the server.
7:10
This should make us,
7:12
refresh the page here.
7:16
So we'll view all course ideas.
7:20
Spark Testing, boy we need that course.
7:24
And if I come in and
I vote, boom there we go.
7:26
Got it.
7:29
One voters.
7:30
That's a little goofy, but that's fixable.
7:33
But there it is.
7:36
When I click this Vote button through,
it really should tell me a message that I
7:37
already voted, so
we don't expect that number to go up.
7:41
Let's go ahead and also make sure
that we can get two voters in there.
7:44
That's the other part of the test.
7:48
So I'm gonna go back to this ideas page.
7:50
It should give me the boot.
7:52
I'm gonna log in as chalkers again.
7:54
Let's have chalkers come in here and vote.
7:57
And we can look, and we can see we
have me and chalkers voting for that.
7:59
Awesome!
8:03
This is really starting
to feel like an app.
8:04
Great job, Slugger!
8:06
See what I did there?
8:08
Slugs and Slugger?
8:09
It's all right.
8:10
I feel like we have
a really interactive app.
8:11
But I think we should challenge
ourselves to do a little bit better.
8:15
When we do those redirects,
they can be a little jarring.
8:19
And if we don't inform our users of
what's going on, they might not notice.
8:21
Or worse yet, assume that their
action worked when in fact it failed.
8:25
Also, we now have some exceptions
that our app can throw, and
8:28
like we saw, they aren't pretty.
8:31
Let's take care of that.
8:33
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