title: Meteor: Why is Iron Router's onBeforeAction called multiple times?
body: <p>When I visit a route in my browser I expect Iron Router to call onBeforeAction once before loading the route. But it looks like it is being called 3 times when first loading the route. </p>
  
  <p>This is an issue for me because I want to put code that redirects the user if they do not have access to that document. </p>
  
  <pre><code>onBeforeAction: -&gt;
    console.log 'called once' #Called 3 times when first loading the route!
    thread = Research.findOne(@params._id)
    console.log thread # This is undefined at first run
    thread = Research.findOne(@params._id)
    if thread?
      Meteor.subscribe 'collabUsers', @params._id
    else
      Router.go '/research'
  </code></pre>
  
  <p>Since it is called multiple times, it causes issues with redirecting. First users that do have access are also redirected because at first thread is undefined. </p>
  
  <p>What I am trying to do if check if the user has access to the data the route depends on, if not then I need to redirect the user. So that is why in onBeforeAction I am trying to pull a document from database and if it exists then I will load the page or else I will redirect or throw and error message at the user.</p>
  
  <p>But I notice that the console.log statement in onBeforeAction is called 3 times when the route is first loaded. And also on the first run the user does not have access to any research threads for some reason (I believe the subscription has not been setup and documents are not accessible on first run) So that causes issues with my trying to see if they have access to the document because on first run nobody has access. </p>
  
  <p>Here is the entire router.coffee code</p>
  
  <pre><code>appendUserData = (array) -&gt;
    _.each array, (item) -&gt;
      user = Meteor.users.findOne(item.userId)
      if user?.profile.firstName? &amp;&amp; user?.profile.lastName?
        item.firstName = user.profile.firstName
        item.lastName = user.profile.lastName
        item.username = user.username
  
  userEnabled = () -&gt;
    if Meteor.user()
      if $(window).width() &gt; 768
        if !$('.show-left').hasClass 'active'
          Meteor.defer -&gt;
            $('.show-left').click()
  
  requireLogin = (pause) -&gt;
    if !Meteor.user()
      @setLayout 'layoutLoggedOut'
      if Meteor.loggingIn()
        @render @loadingTemplate
      else
        @render 'login'
        pause()
    else
      @setLayout 'layout'
      if window.location.pathname is '/' or undefined
        Router.go('addAndSearchPosts')
      else
        Router.go(window.location.pathname)
  
  Router.configure 
    layoutTemplate: 'layout'
    loadingTemplate: 'loading'
    onBeforeAction: -&gt;
      #this code get which ids we need to get data from to render template. Here we need to get data to notification of collab
      params = {}
      params.threadIds = []
      params.userIds = []
      notifications = Notifications.find {userId: Meteor.userId()}
      notifications.forEach (notification) -&gt;
        params.threadIds.push notification.threadId
        params.userIds.push notification.requesterId
  
      @subscribe('notificationDataCollab', params).wait()
    waitOn: -&gt;
      [
        Meteor.subscribe 'myResearch', Meteor.userId()
        Meteor.subscribe "notifications"
      ]
  
  
  Router.onAfterAction userEnabled
  Router.onBeforeAction requireLogin,
    except: 'template1'
  Router.onBeforeAction 'loading'
  Router.onBeforeAction -&gt;
    Errors.clearSeen()
  
  Router.map -&gt;
    @route 'posts_page',
      path: '/posts',
    @route 'template1',
      path: '/template1',
    @route 'login',
      path: '/',
    @route 'addAndSearchPosts',
      path: '/bookmarks',
      waitOn: -&gt;
        Meteor.subscribe 'myBookmarks', Meteor.userId()
      data: -&gt;
        bookmarks: Bookmarks.find
          _userId: Meteor.userId()
    @route 'research',
      path: '/research/:_id',
      waitOn: -&gt;
        [
          Meteor.subscribe 'threadNotes', @params._id, Meteor.userId()
          Meteor.subscribe 'collabUsers', @params._id
        ]
      onBeforeAction: -&gt;
        console.log 'called once'
        #Meteor.subscribe 'collabUsers', @params._id
        # thread = Research.findOne(@params._id)
        # console.log thread
        #thread = Research.findOne(@params._id)
        # if thread?
        #   Meteor.subscribe 'collabUsers', @params._id
        # else
        #   Router.go '/research'
          #Errors.throw('Thread does not exist or you do not have access', false)
      data: -&gt;
        # this code is for appending the user data to pending and current collaborators for this thread
        thread = Research.findOne(@params._id)
        if thread?.pending?.collaborators?.length &gt; 0
          appendUserData(thread.pending.collaborators)
        if thread?.collaborators?.length &gt; 0
          appendUserData(thread.collaborators)
        data = 
          researchThread: thread,
          notes: Notes.find
            _threadId: @params._id
          ,
            sort: 
              date: -1
        data
    @route 'researchHome',
      path: '/research'
    @route 'profileEdit',
      path: '/editprofile'
  </code></pre>
  
  <p>Here is publications.coffee</p>
  
  <pre><code>Meteor.publish 'myResearch', (id) -&gt;
    Research.find({$or: [{_userId: id}, {'collaborators.userId': id}] })
  
  
  Meteor.publish 'threadNotes', (threadId) -&gt;
    Notes.find({_threadId: threadId})
  
  Meteor.publish 'myBookmarks', (userId) -&gt;
    Bookmarks.find({_userId: userId})
  
  Meteor.publish 'collabUsers', (threadId) -&gt;
    Meteor.users.find({}, {fields: {profile: 1, username: 1}})
  
  Meteor.publish 'notifications', -&gt;
    Notifications.find()
  
  Meteor.publish 'notificationDataCollab', (params) -&gt;
    [
      Meteor.users.find({_id: {$in: params.userIds}}, {fields: {username: 1}})
      Research.find({_id: {$in: params.threadIds}}, {fields: {name: 1}})
    ]
  </code></pre>
  
  <p>Any advice on how to handle this is appreciated. </p>