yogiben / meteor-admin

A complete admin dashboard solution
https://atmospherejs.com/yogiben/admin
GNU General Public License v3.0
827 stars 261 forks source link

When opening dashboard get "Cannot read property 'templates' of undefined" #48

Closed epaminond closed 9 years ago

epaminond commented 9 years ago

Get a following exception in client console when switching from a list of elements to dashboard (initial load of dashboard is OK):

Exception in template helper: TypeError: Cannot read property 'templates' of undefined
    at Object.<anonymous> (http://localhost:3000/packages/yogiben_admin.js?8b7c89faf3a3c8e1b1a09fc13d10dbf0289fef5d:1436:89)
    at http://localhost:3000/packages/blaze.js?77c0809654ee3a10dcd5a4f961fb1437e7957d33:2693:16
    at http://localhost:3000/packages/blaze.js?77c0809654ee3a10dcd5a4f961fb1437e7957d33:1602:16
    at Spacebars.call (http://localhost:3000/packages/spacebars.js?3c496d2950151d744a8574297b46d2763a123bdf:169:18)
    at Spacebars.mustacheImpl (http://localhost:3000/packages/spacebars.js?3c496d2950151d744a8574297b46d2763a123bdf:106:25)
    at Object.Spacebars.dataMustache (http://localhost:3000/packages/spacebars.js?3c496d2950151d744a8574297b46d2763a123bdf:138:39)
    at http://localhost:3000/packages/yogiben_admin.js?8b7c89faf3a3c8e1b1a09fc13d10dbf0289fef5d:411:22
    at null.<anonymous> (http://localhost:3000/packages/blaze.js?77c0809654ee3a10dcd5a4f961fb1437e7957d33:2454:44)
    at http://localhost:3000/packages/blaze.js?77c0809654ee3a10dcd5a4f961fb1437e7957d33:1795:16
    at Object.Blaze._withCurrentView (http://localhost:3000/packages/blaze.js?77c0809654ee3a10dcd5a4f961fb1437e7957d33:2029:12)

At that line we have:

if collection.toLowerCase() != 'users' && typeof AdminConfig.collections[collection].templates != 'undefined'

And collection variable at this moment equals empty string ('').

WillHall commented 9 years ago

What version of meteor are you on?

epaminond commented 9 years ago

1.0

yogiben commented 9 years ago

It looks like a problem with your AdminConfig. Double check that the collection names are spelt correctly and that they are global variables.

epaminond commented 9 years ago

Collection names are correct and available globally. AdminConfig is very simple:

AdminConfig = {
  collections: {
    Services: {
      icon:  'wrench',
      color: 'green'
    },
    TradesmenCategories: {
      icon:  'sitemap',
      color: 'yellow'
    }
  }
};

An error trace starts from line 102 of client/html/admin_templates.html and collection is evaluated from view.lookup("admin_collection") function call.

epaminond commented 9 years ago

An error can be reproduced only when switching from non-User collection routes (adminDashboardView, adminDashboardNew and adminDashboardEdit) to dashboard. It doesn't appear for User-related routes.

As far as I see, error appears because before rendering AdminDashboard template an if statement that checks for the dynamic template is evaluated for second time.

For example if I open adminDashboardNew route for collection different from User an {{#if adminTemplate admin_collection 'new'}} will be evaluated normally. But then if I click dashboard link {{#if adminTemplate admin_collection 'new'}} will be evaluated again and then AdminDashboard will be rendered normally.

I could see this by adding breakpoints in the source of compiled package.

WillHall commented 9 years ago

if you comment out the collections object, does the error persist?

epaminond commented 9 years ago

Do you mean in AdminConfig?

WillHall commented 9 years ago

Disregard, I can reproduce the error - looking into it.

WillHall commented 9 years ago

Found what appears to be a fix.

in the router place all session sets in an onAfterAction instead of in the action. This prevents this race condition from occurring.

I am working on a pull request but if you have a local copy of the module running here is the gist

Before:

  @route "adminDashboardView",
    path: "/admin/:collection/"
    template: "AdminDashboardView"
    layoutTemplate: "AdminLayout"
    waitOn: ->
      [Meteor.subscribe('adminCollection', @params.collection), Meteor.subscribe('adminAuxCollections', @params.collection), Meteor.subscribe('adminUsers'), Meteor.subscribe 'adminUser']
    data: -> { documents : window[ @params.collection ].find({},{sort: {createdAt: -1}}).fetch() }
    action: ->
      Session.set 'admin_title', AdminDashboard.collectionLabel(@params.collection)
      Session.set 'admin_subtitle', 'View '
      Session.set 'admin_collection_page', ''
      Session.set 'admin_collection', @params.collection.charAt(0).toUpperCase() + @params.collection.slice(1)
      @render()
    # onBeforeAction: ->
      # AccountsEntry.signInRequired this

After

  @route "adminDashboardView",
    path: "/admin/:collection/"
    template: "AdminDashboardView"
    layoutTemplate: "AdminLayout"
    waitOn: ->
      [Meteor.subscribe('adminCollection', @params.collection), Meteor.subscribe('adminAuxCollections', @params.collection), Meteor.subscribe('adminUsers'), Meteor.subscribe 'adminUser']
    data: -> { documents : window[ @params.collection ].find({},{sort: {createdAt: -1}}).fetch() }
    action: ->
      @render()
    onAfterAction: ->
      Session.set 'admin_title', AdminDashboard.collectionLabel(@params.collection)
      Session.set 'admin_subtitle', 'View '
      Session.set 'admin_collection_page', ''
      Session.set 'admin_collection', @params.collection.charAt(0).toUpperCase() + @params.collection.slice(1)
    # onBeforeAction: ->
      # AccountsEntry.signInRequired this
WillHall commented 9 years ago

PR https://github.com/yogiben/meteor-admin/pull/50

epaminond commented 9 years ago

Thanks for quick fixing! Sorry, I don't know how to test it locally.

WillHall commented 9 years ago

Create packages folder in your app root Clone the repo into packages/admin Meteor remove yogiben:admin Meteor add yogiben:admin

Then just run as normal, it will build the package from the local copy instead of fetching it.

Or you can hold off until @yogiben addresses the open PRs

yogiben commented 9 years ago

@epaminond run meteor update and then meteor list to check the package version is 1.0.1. Please let us know if this problem persists.

Thanks @WillHall.

epaminond commented 9 years ago

@yogiben I've updated package to 1.0.1 and I get another error now: admin actions don't open and an error in client console appears: Route dispatch never rendered. Did you forget to call this.next() in an onBeforeAction?

WillHall commented 9 years ago

How are you producing this error?

epaminond commented 9 years ago

Just opening /admin route. I see layout and Loading... which never changes. If I then press a button to open a collection list Route dispatch never rendered. Did you forget to call this.next() in an onBeforeAction? in client console appears.

yogiben commented 9 years ago

@epaminond Please try updating the admin package. I updated it last night.

epaminond commented 9 years ago

@yogiben thank you for quick response. As of version 1.0.3 collection routes do open correctly. But problem with dashboard remains: a "Loading..." sign appears and never changes. Errors in client console don't appear however.

epaminond commented 9 years ago

Oh, sorry, Dashboard didn't load because my AdminConfig wasn't available on server (adminAllCollections would never publish without it). So subject issue seems to be fixed. Thank you so much!