Sails.js flash message for user registration

主宰稳场 提交于 2019-11-29 10:35:29

问题


I am following Sail.js tutorial from http://irlnathan.github.io/sailscasts/blog/2013/08/27/building-a-sails-application-ep4-handling-validation-errors-with-a-flash-message/

However I ran into a small problem. In the tutorial the author uses registration files inside his user folder and assigns routes in the user controller. He then sends validation errors using flash to the user.

However in my project, the registration files lies in the root folder and I assign the routes from the routes.js file like so

module.exports.routes = {

  '/': {
    view: 'index'
  },

  '/register': {
    view: 'register'
  }

};

Now the problem is to using flash to show users the validation errors while registration. I have used the following in the user controller (create) and it doesn't seem to work

if (err){
    err.success = 0;
    console.log(err);
    req.session.flash = {
        err: err   
    }
    req.flash('error', req.session.flash);
    return res.redirect('/register');
}

Any suggestions?

Sails.js version < 0.10.x based on his other thread output here


回答1:


EDIT: See the Sails documentation here for more information - basically, since you're using static routing, no policies are applied before rendering the view, hence the flash policy isn't working. I'd recommend adding a register action in your UserController and just calling res.view() from there. There's also a StackOverflow post that discusses this, if you want more information.

I do have an alternative I developed for my own project that you can try out (also requires non-static routing).

In your api/policies folder, create a policy flash.js:

// flash.js policy
module.exports = function(req, res, next) {
  res.locals.messages = { success: [], error: [], warning: [] };

  if(!req.session.messages) {
    req.session.messages = { success: [], error: [], warning: [] };
    return next();
  }
  res.locals.messages = _.clone(req.session.messages);

  // Clear flash
  req.session.messages = { success: [], error: [], warning: [] };
  return next();
};

This policy allows for three different flash types: success, warning, and error. It'll create an empty dictionary for each session and clear it on page loads.

I created a service FlashService.js in api/services to more easily flash messages:

// FlashService.js
module.exports = {
  success: function(req, message) {
    req.session.messages['success'].push(message);
  },
  warning: function(req, message) { 
    req.session.messages['warning'].push(message);
  },   
  error: function(req, message) {
    req.session.messages['error'].push(message);
  }
}

Then, in your config/policies.js config file, make sure to assign the flash policy to the controller actions that you want to use flash with:

// config/policies.js
module.exports.policies = {
  '*': [true, 'flash'],
  'UserController': {
    'register': ['flash'],
    // any future actions that want flash
  },
  'AnotherController': {
    'someAction': ['flash', 'somePolicy'],
  }
}

To flash a message in your register action, just use FlashService.success(req, message). Alternatively, you can use FlashService.error and FlashService.warning, depending on how your UI styling works and how much you want to differentiate your flash messages.

In your view, you can put something like this:

<% if (messages && messages['error'].length > 0) { %>
  <div class="alert alert-danger">
  <% messages['error'].forEach(function(message) { %>
    <%= message %>
    <br>
  <% }); %>
  </div>
  <br>
<% } %>
<% if (messages && messages['warning'].length > 0) { %>
  <div class="alert alert-warning">
  <% messages['warning'].forEach(function(message) { %>
    <%= message %>
    <br>
  <% }); %>
  </div>
  <br>
<% } %>
<% if (messages && messages['success'].length > 0) { %>
  <div class="alert alert-success">
  <% messages['success'].forEach(function(message) { %>
    <%= message %>
    <br>
  <% }); %>
  </div>
  <br>
<% } %> 

Of course, you'll have to change the div classes to whatever classes are relevant to your UI.




回答2:


In a normal mvc like rails or cakephp handling flash is something like this: $this->Flash->error('An Error Occurred Message'); then displayed it in an element.

In sails it should be simple as that.

In Controller: req.flash('error', 'An Error Occurred Message');

In View Partial: flash.ejs

<% if (req.session.flash) { %>

    <% if (req.session.flash.success) { %>
    <div data-alert class="alert-box success radius">
        <%= req.flash('success') %>
        <a href="#" class="close">&times;</a>
    </div>
    <% } %>

    <% if (req.session.flash.warning) { %>
    <div data-alert class="alert-box warning radius">
        <%= req.flash('warning') %>
        <a href="#" class="close">&times;</a>
    </div>
    <% } %>

    <% if (req.session.flash.error) { %>
    <div data-alert class="alert-box alert round">
        <%= req.flash('error') %>
        <a href="#" class="close">&times;</a>
    </div>
    <% } %>

<% } %>

On Layout:

<%- partial('partials/flash') %>

Handling Error Message per field should be part in a Validation and Html Helper. (Like for example: https://gist.github.com/mikermcneil/8366092)




回答3:


You can add this export:

module.exports = function flash(req, res, next) {
  if (!req.session.flash) {
    req.session.flash = {};
    req.session.flash['success'] = [];
    req.session.flash['warning'] = [];
  }
  next();
};

and then in the view:

<% if (req.session.flash['success'].length > 0) { %>
<div class="alert alert-success">
  <%= req.session.flash['success'].pop() %>
</div>
<% } %>
<% if (req.session.flash['warning'].length > 0) { %>
<div class="alert alert-warning">
  <%= req.session.flash['warning'].pop() %>
</div>
<% } %>

You can create messages in the controller like this:

req.session.flash['success'].push('Updated successfully');


来源:https://stackoverflow.com/questions/25350841/sails-js-flash-message-for-user-registration

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!