0

So, i'm using express locals to create custom function. I have this:

Menu.getMenu(function(err, menu) {
    app.locals.buildMenuStructure = function(){
        var ids = [];
        for (var i = 0; i < menu.length; i++) {
            ids.push(menu[i]._id); 
        }
        return ids;
    };
}); 

But the problem is that when i add some data to Menu collection the function doesn't know about menu being populated. To see new ids i need to restart the server.

Now i realized that i need to retrieve menus inside buildMenuStructure function to see effect immediately. In that case i need to get the value of getMenu asynchronous function and return it. Something like this:

app.locals.buildMenuStructure = function(){
         var ids = [];
         Menu.getMenu(function(err, menu) {
              for (var i = 0; i < menu.length; i++) {
                  ids.push(menu[i]._id); 
              }
         });
         return ids;
} 

I plan to use async library for that but i can't make it work(( Note! This functions are simplified. Menu.getMenu function is the same as mongoose Menu.find({});

Thanks for your answers.

1 Answer 1

1

Looks like you want to synchronously retrieve the value of asynchronous function, but is's impossible (unless you're using fibers).

The best solution for you is to keep your original code, but to move it into express middleware and use res.locals instead of app.locals:

app.use(function(req, res, next) {
  Menu.getMenu(function(err, menu) {
    res.locals.buildMenuStructure = function(){
      var ids = [];
      for (var i = 0; i < menu.length; i++) {
        ids.push(menu[i]._id); 
      }
      return ids;
    };
    next(err);
  });
})

In this case buildMenuStructure helper will be built anew for every new request.

Here is an example of using both app.locals and res.locals in express with ejs engine.

Sign up to request clarification or add additional context in comments.

3 Comments

I don't have res, req since it's app.locals function. I'm using it in ejs template. And i want to use it anywhere in the site without requests.
I can't see why you don't want to use res.locals instead of app.locals. It'll be available to your ejs template as well. The only difference is that res.locals are scoped to the request and app.locals while app.locals are global to the whole application.
I tried your suggestion but it doesn't work. This is the error - buildMenuStructure is not defined.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.