Nearpoint
Nearpoint

Reputation: 7362

Meteor: DOM element does not exist yet in Template.rendered callback function

I am building an app with Meteor, I have a menu button that is a toggle that shows and hides a sidebar. (green bars)

Once the page is loaded or once the user logs in, if the browser width is greater than 768px I want to click menu toggle button to display it.

Currently I achieve this by reactively checking Meteor.user() because it is called once the page is loaded if the user is logged in and if the user logs in for the first time.

userEnabled = () ->
  if Meteor.user()
    console.log 'user Enabled called ' + menuOpen
    if $(window).width() > 768
      if menuOpen is false
        console.log 'reached inside'
        # Need to use setTimeout before clicking because .show-left element has just been added back to the screen, so we need to wait. I don't like this very much, need to find better method.
        setTimeout ->
          $('.show-left').click()
        , 600

Deps.autorun () ->
  userEnabled()

The problem is that for some reason upon page load, userEnabled() is sometimes called twice, so it open and closes the sidebar. Also another problem is having to use a setTimeout method to wait for the menu toggle element to exist, so I can click it. Without the setTimeout, the element does not get clicked.

So 2 issues

1) client side login callback is called twice

2) I have to use setTimeout to wait for element to exist before clicking it.

How can I solve this issue?

Let me know if you need more information from me, and thanks so much for the help.

Upvotes: 0

Views: 557

Answers (1)

Nearpoint
Nearpoint

Reputation: 7362

Solution (Use Meteor.defer with callback function):

userEnabled = () ->
  if Meteor.user()
    if $(window).width() > 768
      if !$('.show-left').hasClass 'active'
        # Need to use setTimeout before clicking because .show-left element has just been added back to the screen, so we need to wait. I don't like this very much, need to find better method.
        Meteor.defer ->  
          $('.show-left').click()

Router.map ->
  @route 'template1',
    path: '/template1',
  @route 'addAndSearchPosts',
    path: '/',
    onAfterAction: ->
      userEnabled()

Notice instead of using setTimeout before clicking the $('.show-left') button I use Meteor.defer. Meteor.defer waits until the DOM is completely updated and has all elements needed. Otherwise without this when trying to access DOM elements on render, they can end up not working! Use Meteor.defer with a callback to use events on the DOM or update the DOM in rendered callback or in the onAfterAction function.

Upvotes: 1

Related Questions