Routing to a newly created dynamic route?


#1

I’m submitting a form and want to open a editbox on the same page and as the new thread is created change to this new one just after the submit.

Template.categoryCreate.events({
 'submit form': function(e) {
   e.preventDefault();
   var topicName = $(e.target).find('[name=topic]').val();
   var slug = generateSlug(topicName);
   $(e.target).find('[name=topic]').val(""); //Clear input
   thread._id = Thread.insert(thread);
   Category.update({_id: this._id},{$push: {threads: thread._id}});
  Error>> Router.go(this.slug/slug);
   }
 });
}

Now Router.go does not seem to work on /this.slug/slug since they are dynamic I guess?

Router.route('/:category_slug/:thread_slug', function () {

I instead tried adding click event to my Thread collection using observeChanges,

// Look for when new threads are created and we are the author
// In that case switch to that topic and open the editor for us!
(function() {
  var initializing = true;
  Thread.find().observeChanges({
    added: function(id, doc) {
      if (!initializing) {
        console.log(doc);
        var newCategoryLink = $('li.thread-link[data-slug="' + doc.slug + '"]').length;
        console.log("nr: "+newCategoryLink);
      }
    }
  });
  initializing = false;
})();

however this is called before the collection automatically causes the add of that li, so length there is 0.

Any ideas on how to accomplish this? Another more appropriate event I can listen too?


#2

Try something like Router.go(this.slug + "/" + slug); instead. The issue with your current code (it seems) is that you’re actually saying divide this.slug by slug. Wrapping the "/" in quotes concatenates your variables together in one string. The end result is that Iron Router should be able to read this a little better :smile:


#3

Haha, facepalm

This worked:
Router.go("/"+this.slug+"/"+slug);

Just for future reference I had to have a / in the beginning of the string as well:

In this case the route was “/programming/my-new-test-topic”.

Thanks!


#4

What about a named route? (you have to set it up in your routes configuration file.)

Then you can do something like

Router.go("category", {category_slug: this.slug, thread_slug : slug})


#5

Didn’t know about named routes! Very handy.


#6

That sounds like a neat solution.

Here is my routing code:

Router.route('/:category_slug', function () {
  this.layout('main');

  this.render('selectedCategory', {
    to: 'category',
    data: selectedCategoryData
  });

  this.render('noThreadSelected', {to: 'thread'});
}, {
  name: 'category'
});


Router.route('/:category_slug/:thread_slug', function () {
  this.layout('main');

  this.render('selectedCategory', {
    to: 'category',
    data: selectedCategoryData
  });

  this.render('selectedThread', {
    to: 'thread',
    data: function(){
      var thread = Thread.findOne({slug: this.params.thread_slug});
      if(thread){
        $('li.thread-link.current').removeClass('current');
        $('li.thread-link[data-slug="' + thread.slug + '"]').addClass('current');
        return thread;
      }else{
        return {by:'none', date:'unknown', topic:'Thread not found', first:'<p>Seems you arrived at a thread /'+this.params.thread_slug+'/ that does not exist.</p>'};
      }
    }
  });
}, {
  name: 'thread'
});

So where does the category_slug & thread_slug fit in, are those parameters just like to and data?

I did realize I still need an event being called after the route is fully loaded so I can add a “selected” class to the sidebar, any ideas on that?