Return to single post page after edit post - Iron Router


#1

Hello,

My app has it so the url to a post is

example.com/userName/postId

This feature is nice, but it has been giving me a lot of problems too. I’m trying to implement the edit and update feature of a post. That all works fine, but it’s routing back to the single post page after the update is complete. Discover Meteor says to do it this way

  Posts.update(currentPostId, {$set: postProperties}, function(error) {
  if (error) {
    // display the error to the user
    alert(error.reason);
  } else {
    Router.go('singlePost', {_id: currentPostId}); //here
  }
});
},

This doesn’t work for my url arrangement. Here is the code I have so far, which seems like too much.

  var currentPostId = this._id;

  Posts.update(currentPostId, {$set: postProperties}, function(error) {
if (error) { 
  alert(error.reason)
} else {
        Router.go('singlePost',{
           path:'/:_userName/:_currentPostId',
           data:function(){
           Session.set('pageView','single');
          return Posts.findOne(this.params._id);
    }
  }); 
}
}); 

Lots of brackets! I get an error, but thankfully it updates and the app doesn’t crash

Exception in delivering result of invoking ‘/posts/update’: Error: Missing required parameters on path “/:userName/:_id”. The missing params are: [“userName”,"_id"]. The params object passed in was: {“path”:"/:_userName/:_currentPostId"}.

Any help would be much appreciated!


#2

Update, I’m not getting this error with my current code

Exception in delivering result of invoking '/posts/update': Error: Missing required parameters on path "/:userName/:_id". The missing params are: ["userName","_id"]. The params object passed in was: "tyler/kisbMtGMCy6baQKaQ"

with the current code

   Posts.update(currentPostId, {$set: postProperties}, function(error) {
 if (error) {
// display the error to the user
 alert(error.reason);
 } else {
  Router.go('singlePost', user + '/' + currentPostId); //here
 }
});
 },

#3

I think your issue is that you aren’t passing a username key.

Router.go('singlePost', {_id: currentPostId, username:Meteor.user().username});

#4

That worked! The keys!! That is something I’m still learning with JavaScript. JavaScripts basics, access data with keys?


#5

This is not JS-specific but rather required by iron:router because of how you defined your route:

path:'/:_userName/:_currentPostId',

This means that your path will expect both _userName and _currentPostId to be defined whenever it is called or printed as a string, so that’s true for the Router.go() call. If you leave one of those params out, then how should the route know what to put in place of the placeholders. That’s why the above solution worked. Not because of anything JavaScript-specific!

EDIT: And the correct invocation should actually be:

Router.go('singlePost', {_currentPostId: currentPostId, _userName: Meteor.user().username});

(Not sure if and why it may have worked before, but the rule is you need to use the same parameter names as you used in the definition.)

Hope that sheds more light on what’s going on here!


#6

yes, just parameters were “/:userName/:_id” so slightly different names.
but good explanation.


#7

How would that syntax work with

this.route('profile',{
   path:'/:userName',
    data:function(){
     return Profiles.findOne({userName: this.params.userName});
   }
 });

?

or with a userName/post link

this.route('singlePost',{
    path:'/:userName/:_id',
    waitOn: function() {
return Meteor.subscribe('comments', this.params._id);
 },
      data:function(){
      Session.set('pageView','single');
      return Posts.findOne(this.params._id);
    }
  });

#8
this.route('profile',{
   path:'/:userName',
    data:function(){
      console.log(this.params); // now you see what you need to see
     //return Profiles.findOne({userName: this.params.userName});
   }
 });

When in doubt use debugger or print stuff to console!

But yes, your last code snippets seem fine. If something is still not happening the way you intend it to, then

  1. check the Database directly, using meteor mongo and something like db.profiles.findOne()
    1a) or really make sure you publish and subscribe 100% correct and you can now just query everything on the client to see what’s there
  2. check publications, check subscriptions
  3. install msavin:mongol to easily check what’s there on the client
  4. use console.log and debugger (meteor debug for server-side, Chrome dev tools etc for client-side) to see what values variables have exactly, and when.

The beauty of JS and Meteor is that you can poke at everything in console and the debugger. You can see all the data that’s there at any point and thus relatively easily begin understanding what’s actually happening and what different parts of the program are expecting you to do, what input you have to present to them, basically.

HTH!