Search code examples
javascriptmeteorjsxcross-cutting-concerns

Meteor with mantra. Cross cutting concerns


I'm developing application in meteor with mantra. This is a routes.jsx of users module. I want to be able to use requireLogin and redirectUsers in other modules' actions and routes. Or in general how do I deal with cross cutting concerns without violating mantra architecture?

import React from 'react';
import {mount} from 'react-mounter';

import Login from './containers/login';
import Register from './containers/register';
import App from '/client/modules/core/components/app.jsx';

export default function (injectDeps,{FlowRouter,Meteor,LocalState}) {
  let userRoutes = FlowRouter.group({
    prefix:'/user',
    name:'user'
  });

  const AppCtx = injectDeps(App);

  const redirectUsers = () => {
      if(Meteor.userId()){
        const path = LocalState.get('INTERRUPTED_REQUEST_PATH')
          ? LocalState.get('INTERRUPTED_REQUEST_PATH') : '/joke/';
        FlowRouter.go(path);
        return;
      }
  }

  const requireLogin = (path) => {
      if(!Meteor.userId()){
          LocalState.set('INTERRUPTED_REQUEST_PATH',path);
          FlowRouter.go('/user/login');
        return;
      }
  }

  userRoutes.route('/', {
    triggersEnter: [(context,redirect) => {
      if(!Meteor.userId()){
         requireLogin('/user/login');
      }
    }],
    action() {
    }
  });

  userRoutes.route('/login',{
    triggersEnter: [(context,redirect) => {
      redirectUsers();
    }],
    action() {
      mount(AppCtx, { 
        content: () => (<Login />)
      });
    }
  });
}

Solution

  • I have been defining shared functions in /clients/modules/core/libs/ and using it anywhere. I breaks the encapsulation when you use the function outside core module but I haven't found a better way. Let me know if you know one.

    Also, redirecting and authenticating in triggersEnter is considered antipattern.

    Here is a real life example from my open source Mantra app Vym. See there bits:

    The repo is available here if you want to see more of it.

    You could also use this reusable auth composer and handle the authentication on the component level.