Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Java Intro to Java Web Development with Spark Bells and Whistles Build Your Own Flash Messages

What's the approach Craig refers about not repeating yourself with the `moda.put("flash_message"...`? It's not in notes.

Hi there!

In the end of the video, Craig mentions about not repeating yourself with the moda.put(\"flash_message\"... and refers to the Teacher's Notes. Unfortunately I couldn't find any of those.

Can anyone share that solution?

5 Answers

Florian Tönjes
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Florian Tönjes
Full Stack JavaScript Techdegree Graduate 50,856 Points

Hey Vítor,

I solved it by creating a private static inner class within the 'Main' class that looks like this:

    private static class ModelMap extends HashMap<String, Object> {
        void putFlashMessage(Request req) {
            put("flashMessage", captureFlashMessage(req));
        }
    }

It is an extented HashMap of the types <String, Object>. It is not of <String, String>, because then one wouldn't be able to put the List<CourseIdea>, that is returned by dao.findAll(), into it for example.

Next, I changed the redundant code.

For example I changed this:

        get("/", (req, res) -> {
            Map<String, String> model = new HashMap<>();
            model.put("username", req.attribute("username"));
            model.put("flashMessage", captureFlashMessage(req);
            return new ModelAndView(model, "index.hbs");
        }, new HandlebarsTemplateEngine());

To this:

        get("/", (req, res) -> {
            ModelMap model = new ModelMap();
            model.put("username", req.attribute("username"));
            model.putFlashMessage(req);
            return new ModelAndView(model, "index.hbs");
        }, new HandlebarsTemplateEngine());

Kind Regards, Florian

Karrtik Iyer
Karrtik Iyer
3,738 Points

Craig Dennis , can you also please comment on this question since we did not find anything in the teacher's note which specified in the video? Is there any other way then what people have already responded so far? Also can you also please edit the teacher's note section to add this part?

Thanks for replying, Florian.

My solution was kinda similar to yours, but it's a bit more sophisticated since I decided to have an independent class called FlashMessage that has a type and message. I also have a class that is responsible to put/remove the messages from the session.

Adapting your code, it would be something more like:

import static FlashMessageHandler.setFlashMessage;
import static FlashMessageHandler.captureFlashMessage;

class ModelMap extends HashMap<String, Object> {
    final String FLASH_MESSAGE_KEY = "FLASH_MESSAGE_KEY";

    public ModelMap(Request request) {
        this.put(FLASH_MESSAGE_KEY, captureFlashMessage(request));
    }
}

get("/", (req, res) -> {
    ModelMap model = new ModelMap(req);
    setFlashMessage(request, FlashMessage.success("Message goes here"));

    return new ModelAndView(model, "index.hbs");
}, new HandlebarsTemplateEngine());

get("/other", (req, res) -> {
    ModelMap model = new ModelMap(req);

    return new ModelAndView(model, "index.hbs");
}, new HandlebarsTemplateEngine());

Hope it helps other people. :)

Steven Stanton
Steven Stanton
59,998 Points

The teachers notes Craig is referring to seem to be under the previous video. I've cut and paste them below...

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.

Simon Coates
Simon Coates
28,694 Points

thanks Steven for mentioning that. I emailed treehouse with an explanation of the problem. Hopefully they'll fix it.

Craig Dennis
Craig Dennis
Treehouse Teacher

Thank you all! Fixed this!

Hi Vitor, As per my understanding of teacher's notes I can up with the below solution:

before((req, res) -> {
    if(req.cookie("username") != null)
       req.attribute("username", req.cookie("username"));

    Map<String, String> model = new HashMap<>();
    model.put("username", req.attribute("username"));
    model.put("flashMessage", captureFlashMessage(req));
    req.attribute("model", model);
});

get("/", (req, res) -> {
    return new ModelAndView(req.attribute("model"), "index.hbs");
}, new HandlebarsTemplateEngine());

get("/ideas", (req, res) -> {
    Map<String, Object> model = req.attribute("model");
    model.put("ideas", dao.findAll());
    return new ModelAndView(model, "ideas.hbs");
}, new HandlebarsTemplateEngine());

Hope that helps!