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
Doug Hawkinson
Full Stack JavaScript Techdegree Student 25,073 PointsExpress Routing Problem
OK! Third time is the charm. (And hopefully not a redundant charm).
I'm Tech Degree student. Things are quite busy on that side so I'm asking here.
Project 10 (Library Management App) has what should be (IMHO) a tiered menu system.
First Tier navigates to the entities (my term) "Books" or "Patrons" or "Loans".
Second Tier navigation is conditioned by the First Tier selection. But each/all of the entities will navigate to a maintenance function and one or more listing functions.
I have successfully rendered all of the tiers together, stacked one above the other, but the routing to selectively and conditionally render them is eluding me.
I have read and re-read all the documentation I can Google for Express Routing and Promises (I am trying to control the sequence of rendering with a promise). I think I am close but I just can't (in the words of the Doors) break on through to the other side.
Here is a link to my github repo. Is there anyone willing to take a look and point me in the right direction? Keep in mind I'm still a student, so don't assume too much knowledge. I have some knowledge but this is the first real challenge with Express and Routes.
https://github.com/dhawkinson/fsjsProject10
Thanks in advance for the help.
4 Answers
Alexander La Bianca
15,960 PointsThere were some errors in your github repo when starting the app with npm start. To get it started I needed to do:
//IN app.js
app.use('/', index); //change to
app.use('/',index.appRouter);
//IN index.js your function getEntityMenu() was returning etityRouter which was undefined it seems to be a typo
//I changed to
return entityRouter
Having said that. I am unsure of what you are trying to accomplish with your promise in appRouter.get(). I am not an expert with promises at all, but I do see that you are using jQuery in your selectFromAppMenu function. jQuery does not 'exist' in the node.js environment since it is running on the server and not in the browser.
From reading this code, what I assume you are trying to do is that when a user clicks on the links Books, Patrons or Loans you want to bring up the specific page via routing? Please confirm this understanding in order to further help you out.
Alexander La Bianca
15,960 PointsThe reason why index.appRouter is because the app.use('/',middleware) accepts a middleware function. Now the tricky thing is that when reading the documentation is that in the docs, they do not use modularization like you do with your index.js. When you require index.js in app.js you get back what you exported with module.exports. Which is an object with three properties. You were simply providing that object which is not a middleware function. But your appRouter of your index object is. It took me a little digging and reading the error message from running your program to figure out where the issue is.
You are correct. jQuery runs in the browser and node.js on the server. It is tricky sometimes especially when new to node.js. You need to change your mindset as you are not working with the DOM anymore. You are now on the backend where you are trying to read requests and serve responses. That is where your routers come in handy. Say you get a request to /books. Your server needs to have logic in place to serve a response. For example:
router.get('/books',function(req,res){
res.send("<h1>Hi! Welcome to the books page</h1>");
});
You will obviously serve entire pages like you are already doing with res.render("home"). These pages may contains script tags which contain browser side javascript. Now there is where you can include jQuery.
I am still learning as well. I enjoyed going through your project as I have never personally read through a fullstack project like that.
Doug Hawkinson
Full Stack JavaScript Techdegree Student 25,073 PointsAlexander:
Again, thanks. You explain yourself well and have helped a lot.
I am going to clarify one more time. Judging from your explanation on point 1, from the perspective of node.js, my routes/index.js file reconciles down to the output of the module.exports in much the same way as a return statement that passes a value from a function, correct? That is a very helpful piece of understanding.
I am going to bookmark this chain for future reference.
I noticed on the email response that you appear to be about 8 hours ahead of me. I am in Seattle, WA, that would put you in Europe somewhere. Based on your last name I am going to guess, first Spain, second Italy and third France. Am I right? I am constantly amazed at the reach of Treehouse. In any case, thank you so much for your help
Alexander La Bianca
15,960 PointsYes somewhat you can think of module.exports like a return from a function. You then get access to the exported values with the require() function. However, the big main difference between a regular return statement is that when using require to get access to a modules functions, you actually cache that module. Meaning the module will remain the same throughout your application. This can be powerful, but also confusing. That is different with returning a value from a function where each returned value points to a different location. But this is a conversation for a totally different topic.
Not sure why the time says 8 hours ahead lol. I am in Texas.
Doug Hawkinson
Full Stack JavaScript Techdegree Student 25,073 PointsThat's pretty funny. Your most recent response says 8:57PM on September 8, 2017. That was five minutes ago. They must be using GMT, without timezone adjustments.
Doug Hawkinson
Full Stack JavaScript Techdegree Student 25,073 PointsDoug Hawkinson
Full Stack JavaScript Techdegree Student 25,073 PointsAlexander: I appreciate your comments for a couple of reasons.
The first being this change "app.use('/',index.appRouter);". Please tell me about that one.. I all of my reading and re-reading of documentation I never ran across anything that would have let me to make that change, which only exemplifies the adage that a little knowledge is a dangerous thing. I am still green enough that I never would have picked that out. Please explain.
The second helpful tidbit was that fact that jQuery is not available in node. I never ran across anything that would have enlightened me in that area either. I suppose I would have eventually come to that understanding through trial by fire, but I don't believe I ever ran across that explicit knowledge. To clarify that is because node.js is server-side and jQuery is browser side, correct?
And thirdly, thanks for pointing out the typo. That was simply a can't-see-the-forest-for-the-trees experience. I have been looking at the code for so long that it just "looked right".
If you wouldn't mind, please get back to me on the first point (Well, and confirm the second) I see what you are saying but don't make the connection to why that would matter. I think I would learn something.
Having said all that, in spite of the benefit I derived from you comments, I have been pretty much been convinced that what I was trying to do results in a sub-par UX. I had a discussion with one of the mentors and he pointed me to some resources that have nearly completed the process of changing my mind. I just need to finish the tutorials (UX Basics) to complete the loop. I will then change my approach and what I was trying to do will not be what I am going to do.
Nonetheless, your comments have been valuable. It is amazing how God turns even our mistakes into a blessing.
Thank you.