Conditional Jade templates, user logins - javascript

1st Question
I'm current working on an express/jade web application and quite new to it.
I've followed some tutorials and examples and put together most of the back-end and have a full stack.
What I'm currently trying to do is check for if a user is currently logged in and render jade that's dependent on the outcome of that check.
I'm aware that one can natively put JavaScript in jade templates. I have a home page and would like to show a different nav-bar depending on the log-in state of the current user.
previously in my routing I was able to simply check the for this like
app.get('/', function(req, res){
if (req.cookies.user == undefined || req.cookies.pass == undefined)
other code...
Can the same be done in a Jade template? How would I go about this? Is this a bad approach are there easier or better ways to tackle this?
2nd Question
What I'm curious about now is, is this request object just something in the DOM I can access and check with something like Jquery?
A follow up question I have here is javascript specific. I come from a Java OO background and this is the first time I've played with JS, the fact that it's a functional language leaves me confused. For example referring to the anonymous function above as the 2nd argument to the app.get function, where is it getting req and res from? Does express/node simply hand it a request and response or how does that work?

about 1st question, no its not a bad approach usually that kind of checking is left outside of the jade document for keeping the document in a clean state.
you can try to expose Objects to res.render which makes available the data to document. so to avoid much of the javascript code in jade template just expose a user object.
var user={loggedIn:false}
about 2nd question, req, res are passed on each time , by express using the middleware pattern, until a res.send or res.end or res.render (and other) are called which stop the execution of middleware stack.
a simple example would be
app.get("/",
function(req,res,next){
req.hello=world; if(next){next()};
}
,function(req,res){
res.send(200,req.hello);
});

Related

How to determine the necessary paramaters in javascript callbacks

I've been dipping my feet into javascript and more specifically node.js but I'm having trouble identifying required parameters for callbacks.
For example, when creating a route through Express, I can have the following
app.get('/', function() {
console.log('this is a route');
});
Which will execute without giving me any trouble. However, having seen multiple examples, I know that I probably want to have something more along the lines of
app.get('/', function(req, res) {
res.render('index');
});
But without having seen examples or documentation (which is sometimes just a couple unclear examples) is there a consistent way to determine what parameters a callback is expected to have?
I hope I've been clear.
Without documentation, or inspecting the source of the function executing the callback, you wont easily know.
However, you can intercept them with some exploratory code and see what you get:
app.get('/', function() {
console.log(arguments);
});
The arguments keyword here is the list of arguments passed to the callback function, so this will let you see what you got. If it tell you something is a Express.Request or something, this at least lets you know what to try to find in the docs.
But outside of standard javascript, using typescript or flow helps with this since it adds static types to javascript. If this function is typed, then your editor will then know arguments the callback function expects and can help you fill them in.
Since you're using Express, the documentation is pretty clear - It depends on your route parameters and whether or not you're using middleware. There is no hard and fast rule, it genuinely depends on your route's function.
Your first example "works" because you're only printing to the console, but without the res response object you'll notice that that the request response returns nothing.
Start with req and res for each and expand as needed.

NodeJS - store session data per HTTP request in a "global" variable

There is a similar thread that is currently two years old, and it pretty much sums up what I want.
To give you an example, for the C# developers there is a single Session object which stores user's session and is accessible anywhere, in each class, .dll, you name it. It's stored per-request.
I need basically the same thing. My users have simple permissions, they are either admins or have roughly 5 assigned elements. I'm storing these 5 elements in an access token, so basically in the first middleware I have an array of ids which are user's permissions.
What I want is not to pass a permissions object around, especially not to pass them to service/DAL layers which are responsible for querying the database since it's pretty ridiculous for getAllCities function to receive permissions object and a callback as parameters. Or whatever object for that matter.
I cannot store the values in global variables since the globals are, well, global. I don't want to pass the variables to each function, so I would probably fall back to rounding the databases for user's permissions per each call, but that's just.. Meh.
I also don't want to mess to much with dozens of libraries etc., because I believe this is a common problem that people stumble upon and I wonder what are the best solutions.
On the thread linked above there is a robust solution which I would frankly want to avoid. Everything I've used in Node has been plug-and-play, and implementing custom middlewares and pipelines for this "small" thing seems like an overkill.
Two years later, is there a better solution out there to this problem?
You would typically use something like express-session to manage a session for each user and then each incoming request would automatically have access to that session object for that user in the request handler. You can then store any user-specific information in that session object.
Any functions that you want to execute in a given request should either be passed the request object (from which they can get access to the session) or just pass them the session object or some user-specific object you pulled out of the session. In node.js the place for user-specific information is in the request object. There is no "global" space to store it that all other functions can access it.
If you want a function to be able to access request or session specific data, then pass that data to the function. That's how it works. If this appears to be a problem to you, then you have to rethink how your code is architected and perhaps use objects/methods that can maintain state more easily.
node.js does not have a thread per request that can have it's own thread state. Instead, in an http server, you use the request object as the core state for a given request and you pass it to functions that need it. Or, if you're using a user session, you can extract that from the request object and then pass the session around as needed.
I don't want to pass the variables to each function, so I would
probably fall back to rounding the databases for user's permissions
per each call, but that's just.. Meh.
It sounds to me like too much of your code is just plain functions rather than methods on an object. If you think of your code as a user object that has methods on it, then you can form a user object in the initial request and then call methods on that user object for most things you would want to do that are user-specific. The user object then is a nice simple repository for user-specific information (such as permissions) and ALL methods on the object will have access to it without having to pass it to every function.
I repeat, if passing the user state around seems like a burden, then it's probably because your code is not architected in a way that makes it easy. Rather than looking for a work-around for something that is not the way node.js works, you should think about architecting your code to make these kinds of things easy so your architecture more closely matches the needs of your code given the way the underlying system works.
implementing custom middlewares and pipelines for this "small" thing
seems like an overkill.
Session middleware is not a small thing. It's core to any application that maintains user-specific data across requests and wants easy access to it on each new request from that same user. It's generally how you manage user state in node.js.
To give you an example, for the C# developers there is a single
Session object which stores user's session and is accessible anywhere,
in each class, .dll, you name it. It's stored per-request.
That simply isn't how node.js works at the lowest architectural level. And, the sooner you realize that and start designing your code to align with the way node.js actually works (rather than the way some other system works), the sooner you will find node.js coding flows naturally. It's something new to learn, not to be avoided or worked-around.

Encapsulating nested component port communication in Elm?

I have a reusable Elm component that is intended to be reused in multiple places (in the style of the guide tutorial. I have a Javascript function that I would like to communicate with via ports, but creating a port subscription causes every "instance" of my component to receive every message that I send back from Javascript.
Ideally, parent components should not need to do any filtering beyond the usual Cmd.map ChildMsg. The simplest solution I can come up with is to add an ID to each child model and filter in the child's own update function, but this is a bit unfortunate, and requires me to fabricate an ID if one doesn't already exist.
As an example of my ideal result, the Http modules allows you to return a task and receive the result back, addressed only to the specific instance that requested it. I've managed to emulate this behavior with a simplistic Native module: https://github.com/tgecho/elm-custom-task-example
function getNumber(number) {
return _elm_lang$core$Native_Scheduler.nativeBinding(function(callback) {
return callback(_elm_lang$core$Native_Scheduler.succeed(number));
});
}
Then my component can call this function by returning a task Task.perform NaN Increment (Number.getNumber 1) and will receive the result back as an Increment message.
What am I missing? Is there a way to encapsulate port communication without writing Native code or adding IDs to everything?

Global scope for every request in NodeJS Express

I have a basic express server that needs to store some global variables during each request handling.
More in depth, request handling involves many operation that need to be stored in a variable such as global.transaction[]
Of course if I use the global scope, every connection will share information of its transaction and I need a global scope because I need to access the transaction array from many other modules, during my execution.
Any suggestion on this problem? I feel like is something very trivial but I'm looking for complicated solutions :)
Many thanks!
UPDATE
This is a case scenario, to be more clear.
On every request I have 3 modules (ModuleA, ModuleB, ModuleC) which read the content of 10 random files in one directory. I want to keep track of the list of file names read by every request, and send back with res.write the list.
So ModuleA/B/C need to access a sort of global variable but the lists of request_1, request_2, request_3 etc... don't have to mix up.
Here is my suggestion avoid global state like fire.
It's the number one maintenance problem in Node servers from my experience.
It makes your code not composable and harder to reuse.
It creates implicit dependencies in your code - you're never sure which piece depends on which and it's not easy to verify.
You want the parts of code that each piece of an application uses to be as explicit as possible. It's a huge issue.
The issue
We want to synchronize state across multiple requests and act accordingly. This is a very big problem in writing software - some say even the biggest. The importance of the way objects in the application communicate can not be overestimated.
Some solutions
There are several ways to accomplish sharing state across requests or server wide in a Node server. It depends on what you want to do. Here are the two most common imo.
I want to observe what the requests do.
I want one request to do things based on what another request did.
1. I want to observe what the requests do
Again, there are many ways to do this. Here are the two I see most.
Using an event emitter
This way requests emit events. The application reads events the requests fire and learns about them accordingly. The application itself could be an event emitter you can observe from the outside.
You can do something like:
request.emit("Client did something silly", theSillyThing);
And then listen to it from the outside if you choose to.
Using an observer pattern
This is like an event emitter but reversed. You keep a list of dependencies on the request and call a handler method on them yourself when something interesting happens on the request.
Personally, I usually prefer an event emitter because I think they usually solve the case better.
2. I want one request to do things based on what another request did.
This is a lot tricker than just listening. again, there are several approaches here. What they have in common is that we put the sharing in a service
Instead of having global state - each request gets access to a service - for example when you read a file you notify the service and when you want a list of read files - you ask the service. Everything is explicit in the dependency.
The service is not global, only dependencies of it. For example, it can coordinate resources and the data, being some form of Repository).
Nice theory! Now what about my use case?
Here are two options for what I would do in your case. It's far from the only solution.
First option:
Each of the modules are an event emitter, whenever they read a file they emit an event.
A service listens to all their events and keeps count.
Requests have access to that service explicitly and can query it for a list of files.
Requests perform writes through the modules themselves and not the added service.
Second option:
Create a service that owns a copy of module1, module2 and module3. (composition)
The service delegates actions to the modules based on what is required from it.
The service keeps the list of files accessed since the requests were made through it.
The request stops using the modules directly - uses the service instead.
Both these approaches have advantages and disadvantages. A more complicated solution might be required (those two are in practice pretty simple to do) where the services are abstracted further but I think this is a good start.
One simple way is storing data on the request object.
Here is an example (using Express):
app.get('/hello.txt', function(req, res){
req.transaction = req.transaction || [];
if (req.transaction.length) {
// something else has already written to this array
}
});
However, I don't really see how you can need this. When you call moduleA or moduleB, you just have to pass an object as argument, and it solves your issue. Maybe you're looking for dependency injection?
using koa ctx.state doc for this scenario, in express I believe this Plugin should serve your needs.
in order to keep some data that will be resused by another request on the save server app, I propose to use session in expresse and avoid any global state or any props drilling from one request to another.
In order to manage session state in express you could use :
session-file-store save the session in a file
express-mongodb-session : save the session in mongoDb
mssql-session-store -> for a relation db
Of course there is another technique ti manage session in NodeJs.

Lift session-valid ajax callback from a static javascript

I am currently implementing a graph visualisation tool using lift on the server side and d3 ( a javascript visualisation framework) for all the visualisation. The problem I have is that in the script I want to get session dependent data from the server.
So basically, my objective is to write lift-valid ajax callbacks in a static js script.
What I have tried so far
If you feel that the best solution is one that I already tried feel free to post a detailed answer telling me how to use it exactly and how it completely solves my problem.
Write the ajax callback in another script using lift and call it from the main script
This solution, which is similar to a hidden text input is probably the more likely to work. However it is not elegant and it would mean that I would have to load a lot of scripts on load, which is not really conveniant.
This seems to be one of the prefered solutions in the lift community as explained in this discussion on the mailing list.
REST interface
Usually what one would do to get data from a javascript function in lift is to create a REST interface. However this interface will not be linked to any session. This is the solution I got from my previous question: Get json data in d3 from lift snippet
Give function as argument of script
Another solution would be to give the ajaxcallback as an argument of the main script called to generate my graph. However I expect to have a lot of callbacks and I don't want to have to mess with the arguments of my script.
Write the whole script in lift and then serve it to the client
This solution can be elegant, however my script is very long and I would really prefer that it remainss static.
What I want
On client side
While reviewing the source code of my webpage I found that the callback for an ajaxSelect is:
<select onchange="liftAjax.lift_ajaxHandler('F966066257023LYKF4=' + encodeURIComponent(this.value), null, null, null)" name="F96606625703QXTSWU" id="node_delete" class="input">
Moreover, there is a variable containing the state of the page in the end of the webpage:
var lift_page = "F96606625700QRXLDO";
So, I am wondering if it is possible to simulate that my ajaxcall is valid using this liftAjax.lift_ajaxHandler function. However I don't know the exact synthax to use.
On server side
Since I "forged" a request on client side, I would now like to get the request on client side and to dispatch it to the correct function. This is where the LiftRules.dispatch object seems the best solution: when it is called, all the session management has been made (the request is authentified and linked to a session), however I don't know how to write the correct piece of code in the append function.
Remark
In lift all names of variables are changed to a random string in order to increase the security, I would like to have the same behavior in my application even if that will probably mean that I will have to "give" the javascript these values. However an array of 15 string values is still a better tradeoff than 15 functions as argument of a javascript function.
Edit
While following my research I found this page : Mapping server functions to client actions which somehow explains the goal of named functions even if it stil didn't lead me to a working solution.
Quick Answer
Rest in Lift does not have to be stateless. If you register your RestHelper with LiftRules.dispatch.append, then it will be handled statefully and Session information will be available through the S object as usual.
Long Answer
Since you seem interested, and it's come up on SO before, here's a more detailed explanation of how server-side functions are registered and called in Lift. If you haven't worked with Lift for some time, look away. What follows should not in any way be used to evaluate Lift or its complexity. This is purely library developer level stuff and a majority of Lift users go about their development blissfully unaware of it.
How it works
When you create stateful callbacks, typically by using the methods within the SHtml object, what you are really doing is registering objects of type S.AFuncHolder within the context of the users session, each with a unique ID. The unique ID that was generated during this process is what you're seeing when you come across a pattern like F96606625700QRXLDO. When data is submitted, via form post, ajax, or whatever, Lift will check the request for these function ids and execute the associated function if they exist. There are several helpers that provide more specific types of AFuncHolder, like S.SFuncHolder (accepts a single string query parameter) and S.BinFuncHolder (parameter is multipart form data) but they all return Any and behind the scenes Lift will collect those return values to create the proper type of response. A JsCmd, for instance, will result in a JavaScriptResponse that executes the command. You can also return a LiftResponse directly.
How to use it
AFuncHolders are registered using the S.fmapFunc method. You'd call it like this
S.fmapFunc(SFuncHolder({ (str: String) =>
doSomethingAwesomeWithAString(str)
}))(id => <input type="text" name={id} value=""/>)
The first parameter is your function, wrapped in the proper *FuncHolder type and the second parameter is a function that takes the generated id and outputs something. The something that gets output is what you will include on the page. It should somehow result in the id being sent to the server as a query parameter so that your function is executed.
Putting it all together
You could use the above to make your own Ajax calls, but when Lift makes an ajax call there are a few other considerations:
1) Most browsers only allow so many simultaneous connections to a given domain. Three seems to be the magic number.
2) AFuncHolders will often close over the scope of the snippet they are contained within and if multiple ajax requests are handled at once, each in its own thread, bad things can happen.
To combat these issues, the liftAjax.lift_ajaxHandler function queues each ajax request, ensuring that only one at a time is sent to the server.
The drawback to this approach is that it can make it difficult to make an Ajax call where the result needs to be passed to a callback. JQuery autocomplete, for instance, provides a callback function when input changes that accepts a list of matches. If you are manually calling LiftAjax.lift_ajaxHandler though, you can provide your own callback functions for success & error and I would recommend that you look at the source of those functions in your browser for more information on how they work.
There's actually more to it, like how Lift restores RequestVars on ajax callbacks (which is where the lift_page comes in, but that's about all I'm prepared to explain over coffee on a Saturday morning :)
Good luck with your app!

Categories

Resources