Meteoro: Por que o onBeforeAction do Iron Router é chamado várias vezes?
Quando visito uma rota no meu navegador, espero que o Iron Router chame onBeforeAction uma vez antes de carregar a rota. Mas parece que está sendo chamado três vezes ao carregar a rota pela primeira vez.
Esse é um problema para mim, porque quero colocar um código que redirecione o usuário se ele não tiver acesso a esse documento.
onBeforeAction: ->
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'
Como é chamado várias vezes, causa problemas no redirecionamento. Os primeiros usuários que têm acesso também são redirecionados porque, no primeiro segmento, é indefinido.
O que estou tentando fazer se verificar se o usuário tem acesso aos dados dos quais a rota depende; caso contrário, preciso redirecionar o usuário. É por isso que no onBeforeAction eu estou tentando extrair um documento do banco de dados e, se ele existir, carregarei a página ou redirecionarei ou lançarei uma mensagem de erro para o usuário.
Mas notei que a instrução console.log em onBeforeAction é chamada 3 vezes quando a rota é carregada pela primeira vez. E também, na primeira execução, o usuário não tem acesso a nenhum segmento de pesquisa por algum motivo (acredito que a assinatura não foi configurada e os documentos não estão acessíveis na primeira execução). Isso causa problemas na minha tentativa de verificar se eles têm acesso. ao documento porque, na primeira execução, ninguém tem acesso.
Aqui está o código roteador inteiro.
appendUserData = (array) ->
_.each array, (item) ->
user = Meteor.users.findOne(item.userId)
if user?.profile.firstName? && user?.profile.lastName?
item.firstName = user.profile.firstName
item.lastName = user.profile.lastName
item.username = user.username
userEnabled = () ->
if Meteor.user()
if $(window).width() > 768
if !$('.show-left').hasClass 'active'
Meteor.defer ->
$('.show-left').click()
requireLogin = (pause) ->
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: ->
#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) ->
params.threadIds.push notification.threadId
params.userIds.push notification.requesterId
@subscribe('notificationDataCollab', params).wait()
waitOn: ->
[
Meteor.subscribe 'myResearch', Meteor.userId()
Meteor.subscribe "notifications"
]
Router.onAfterAction userEnabled
Router.onBeforeAction requireLogin,
except: 'template1'
Router.onBeforeAction 'loading'
Router.onBeforeAction ->
Errors.clearSeen()
Router.map ->
@route 'posts_page',
path: '/posts',
@route 'template1',
path: '/template1',
@route 'login',
path: '/',
@route 'addAndSearchPosts',
path: '/bookmarks',
waitOn: ->
Meteor.subscribe 'myBookmarks', Meteor.userId()
data: ->
bookmarks: Bookmarks.find
_userId: Meteor.userId()
@route 'research',
path: '/research/:_id',
waitOn: ->
[
Meteor.subscribe 'threadNotes', @params._id, Meteor.userId()
Meteor.subscribe 'collabUsers', @params._id
]
onBeforeAction: ->
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: ->
# 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 > 0
appendUserData(thread.pending.collaborators)
if thread?.collaborators?.length > 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'
Aqui estão publicações. Café
Meteor.publish 'myResearch', (id) ->
Research.find({$or: [{_userId: id}, {'collaborators.userId': id}] })
Meteor.publish 'threadNotes', (threadId) ->
Notes.find({_threadId: threadId})
Meteor.publish 'myBookmarks', (userId) ->
Bookmarks.find({_userId: userId})
Meteor.publish 'collabUsers', (threadId) ->
Meteor.users.find({}, {fields: {profile: 1, username: 1}})
Meteor.publish 'notifications', ->
Notifications.find()
Meteor.publish 'notificationDataCollab', (params) ->
[
Meteor.users.find({_id: {$in: params.userIds}}, {fields: {username: 1}})
Research.find({_id: {$in: params.threadIds}}, {fields: {name: 1}})
]
Qualquer conselho sobre como lidar com isso é apreciado.