21

I'm trying to understand when it's best to use each of the following. Here is my rudimentary understanding:

app.locals -- good for storing global variables at the app level. all users/sessions will see the same values for these variables. the variables are available to all views.

res.locals -- good for storing variables for the specific request/response cycle. the variables are only available to the view associated with the response.

req.session -- good for storing variables associated with the unique user session (e.g., user name). these variables should be available to all views for the unique user/session.

The specific use case I have is as follows: A user runs query which retrieves data from mongodb. I now want the result of this query, which is a JSON array, available as a variable to ALL of the views (HTTP requests). What's the best way to "store" the result array so that each view can access it?

Dale K
  • 25,246
  • 15
  • 42
  • 71
  • You pretty much answered the question yourself. req.locals is for data that should be available in the views for the current request. – Andreas Hultgren Mar 08 '13 at 14:59

1 Answers1

5

I now want the result of this query, which is a json array, available as a variables to ALL of the views. What's the best way to "store" the result array so that each view can access it?

When you say "available to ALL of the views" I assume you mean across all HTTP requests. If that is the case then you need to be aware that HTTP is a stateless protocol and does not provide for this. You'll need to develop your own mechanism for this.

One way of doing this is by cacheing this information (the array) on the server and retrieve it on every request (for example, retrieve it from memory rather than from MongoDB). You'll store a session ID on the cookie and based on this ID fetch it from cache when another requests comes through. There are several cache tools available (e.g. redis, memcached, et cetera) that you can chose to store the information in memory.

You could also cookie this information (the array itself) in which case it will be send back and forth between the client and the server on every HTTP request and very likely won't be a very good idea unless the data is very small.

Hector Correa
  • 26,290
  • 8
  • 57
  • 73
  • 1
    If you store the data in `app.locals`, and don't run more than one Node process (i.e. you don't use `cluster`), it will be available to all views, even across requests. – robertklep Mar 08 '13 at 15:19
  • @robertklep -- that's what I originally did, stored the data in app.locals, but then I ran test with two PCs making HTTP requests and they both saw the same data! I don't want to share the data between clients. –  Mar 08 '13 at 15:27
  • 2
    So you want them available in all views but only for the user which triggered the query? Use `req.session` (again, in your question you already answer yourself ;-) – robertklep Mar 08 '13 at 15:29
  • 1
    @JasonGelinas if you store it in app.locals you'll need to store the "session ID" associated with it so that you can fetch that particular value on the next request. – Hector Correa Mar 08 '13 at 15:31
  • @robertklep -- could you explain the inssue with using app.locals and cluster modules like PM2? Why wouldn't the app.local value be available to all processes? –  Oct 15 '14 at 20:46
  • 2
    @KaneSchutzman in this particular case, the user wants to trigger a MongoDB query (and store its results), which I assumed would take place when the Express app is up and running already. If you use `cluster` (or, basically, a `fork()`) to handle your Express routes in, changes to `app.locals` in one subprocess will not be reflected in other subprocesses. – robertklep Oct 16 '14 at 06:28