bminer / node-blade

Blade - HTML Template Compiler, inspired by Jade & Haml
Other
320 stars 28 forks source link

Showing current user in Meteor #173

Closed Polyrhythm closed 11 years ago

Polyrhythm commented 11 years ago

I can't for the life of me get this to work. Here's some JS I have in the client for Meteor:

if Meteor.isClient 
  Meteor.startup ->
    Template.body.user = ->
      if Meteor.users()
        if ! Meteor.loggingIn()
          return Meteor.users().username

How do I have my Blade template checking for the existence for user? I tried #{user} but I get errors that user is not defined yet. If I check for the existence for a user with

- if (#{user})

I get an error. Not really sure how to get the template to return a current user without just spitting it back before the user is loaded from Meteor.

bminer commented 11 years ago

Might be a load order issue. Your Blade document is probably rendering before Template.body.user is defined. Try moving the Template.body.user helper function so that it is declared outside of Meteor.startup.

bminer commented 11 years ago

This issue is documented here: https://github.com/bminer/node-blade/wiki/Using-Blade-with-Meteor#troubleshooting-and-known-issues

If that doesn't solve it, please feel free to post back here.

Polyrhythm commented 11 years ago

Yeah, still a problem. I tried moving

if Meteor.isClient 
  Meteor.startup ->
    Template.body.user = ->
      if Meteor.users()
        if ! Meteor.loggingIn()
          return Meteor.users().username

to a directory called "zCode" inside my root app folder. My view in question is

#container
  .container

    header.main-header
      a.nav-link.root(href="/") root
      a.nav-link(href="/login") #{user}

I even tried putting the #{user} call inside of different Blade partial and including that partial in the Body.blade template. No difference. I get an error in the console that user is not defined and no server error from Meteor.

If I try

- if (#{user})
   a.user #{user}

I get Meteor terminal errors originating from Blade. I've also tried - if (user)

And just for clarity, yes, I currently have a user logged in. I get a result with:

Meteor.users()

in the console once the page is loaded.

If I remove the Meteor.startup line then I get a console error in the browser that Template is not defined.

bminer commented 11 years ago

Hmmm...

- if (#{user})
   a.user #{user}

... is invalid syntax, so that definitely won't work.

Try using - if(locals.user) That way, if the user helper is undefined, your view won't complain about "user is not defined." Another thing to do is to rename your view helper from user to something like user2 just in case it's a namespace issue.

Also, if it still doesn't work, could you copy/paste the HTML source code for your Meteor app? Or, can you provide the URL for your project?

Polyrhythm commented 11 years ago

If I try - if(locals.user I get the following error:

Uncaught TypeError: Property 'users' of object #<Object> is not a function
    at /Users/ryan/Development/Meteor/hacker/views/body.blade:6:7

4 |     header.main-header
5 |       a.nav-link.root(href="/") root
6 >       - if(locals.user)
7 |         a.nav-link(href="/#{user}") #{user}
8 |         a.nav-link(href="#") logout
9 |       - else

Also tried renaming the helper to avoid namespace issues to no avail.

The URL to my app (with the #{user} calls removed from the view) is http://hacker.meteor.com/landing

The repo is here: https://github.com/Polyrhythm/hacker

bminer commented 11 years ago

That means that your helper is working. The problem is here:

if Meteor.isClient
  Meteor.startup ->
    Template.body.user = ->
      if Meteor.users()
        if ! Meteor.loggingIn()
          return Meteor.users().username # <------------- problem: Property `users` is not a function

But, yeah... your problem before was a startup issue that will be fixed once the Meteor guys fix this bug: https://github.com/meteor/meteor/issues/181

Basically, right now you are required to put Template.body.helper_name = funciton() ... calls inside of Meteor.startup to ensure that the Template actually exists before a helper is added to it. This is unfortunate since the views themselves may rely on the helpers, as well, which is why body.blade is wrapped in a Meteor.startup call, as well.

In your case, though, you are using Angular to load views depending on the URL, I presume. The problem occurs when you call angular.bootstrap before the view helper is loaded. This should also be wrapped in a Meteor.startup routine, as well and placed after your view helpers are defined.

Fix your view helper first... the whole "users is not a function" thing. Then, move the following code to the bottom of startup.coffee:

  angular.element(document).ready ->
      angular.bootstrap document, ['hackerApp']

Hope that helps!

bminer commented 11 years ago

Closing this issue for now, but please feel free to post back here. Thanks!

Polyrhythm commented 11 years ago

* UPDATE *

Hold up on using up your time on this. I may be on to something to fix...

Original issue text below:

I'm still having all kinds of problems. :(

If I wrap the Angular bootstrap inside of the Meteor.startup function, I get a crazy side effect where the DOM is actually loaded twice. It looks like Body.blade loads on its own and then Angular kicks in and loads a whole new set of the DOM on top of that. The really interesting bit is that the User thing will work fine on the version that Blade loads but not the version that Angular loads. Again, check out hacker.meteor.com to see it in action - you can scroll down to see the second DOM and create an account to see the whole thing working on the "blade" version of the DOM.

If you think this is actually an issue with the Angular smart package I'm using (https://github.com/olanod/ng-meteor) then I can bring them into the conversation.

I should add that, of course, this doesn't appear to pick up a logged-in user if I keep the Angular stuff out of the Meteor.startup function. It doesn't give me any errors now, though.

As a side note, check out the console on sign in or logging in - lots of what looks like repetitive activity. Not sure if that's a normal Meteor thing or an effect of me loading the DOM twice.

Thanks for the help thus far in any case.

Polyrhythm commented 11 years ago

Yeah I can't get this to play nicely with Angular. Either your blade templates load the user fine without Angular, or I use Angular and end up generating two versions of the DOM.

bminer commented 11 years ago

Again, this is more of a Meteor issue than anything else, I believe. The Blade smart package cannot enforce the load order of files, and therefore, it cannot ensure that the templates are loaded before anything else. I'm hoping that bugs like this get cleaned up in the next few weeks.