beforeModel replaceWith to /users/ URL broke in 1.8.0.beta11

Part of one of my plugins broke after installing the recent update from Discourse 1.8.0.beta10 to beta11 (11+3, to be precise).

Any help understanding what broke and how to fix it would be much appreciated.

Background

The plugin adds two URLs/routes to Discourse relevant to the problem:

  • /users/<username>/link-opus
    • This displays & edits extra information tied to <username>'s account.
    • Normal users may only view their own pages. Admins can view anyone’s page.
  • /users/link-opus
    • Exists to simplify instructions. We can tell people “go to this URL” and it should work for everyone.
    • If the user is not logged in, it shows a page asking them to create an account or log in.
    • If the user is logged in, it should redirect them to the other URL, the one specific to their username.
      This redirect is what has broken.

The problem code

The diversion from /users/link-opus to /users/<username>/link-opus used to be done like this, by calling replaceWith from beforeModel:

export default Discourse.Route.extend({

	beforeModel() {
		// If a user is logged in, take them to their personal account-linking page.
		// Otherwise, we'll display the landing page with instructions on what to do.
		if (this.currentUser) {
			this.replaceWith("/users/" + this.currentUser.get("username") + "/link-opus");
		}
	},
	// ... other code omitted...
}

That worked great until the recent Discourse update. Now, it results in an error message saying the page is private of missing.

The strange thing is that it puts the correct URL into the browsers address bar, and if I simply push Refresh or click F5 in the browser, the /users/<username>/link-opus page loads correctly.

Theories

I suspect the replaceWith call may need a user model or something passed as an extra parameter, although it certainly did not until now, so maybe not. I tried doing that without much luck, but I am not sure I did the correct thing.

I also looked through recent commits but I could not see anything that sounded like it would have broken this. There was one about removing warnings from duplicate routes, but it doesn’t look relevant. Another mentions not loading the user object if it isn’t needed, but I couldn’t see how it would affect what I am doing. Others commits don’t seem to involve routing or the user object, at least that I could notice.

Workaround (not great)

As a temporary workaround, I have swapped the this.replaceWith... line with one which tells the browser itself to go to the other URL:

window.location.assign("/users/" + this.currentUser.get("username") + "/link-opus");

While that ends up in the correct place and loads the page correctly, it means the generic page is displayed for a moment while the user-specific page loads. That’s bad as the generic page displays information that is incorrect if someone is logged in.

Finally, here’s the relevant file to save having to search for it, in case the rest of it is important. This includes the workaround, so the broken code is currently commented out, at the time of posting.

https://github.com/LeoDavidson/discourse-directoryopus/blob/master/assets/javascripts/discourse/routes/linkopuslanding.js.es6

Many thanks for your time!

Are you sure it isn’t due to “/users/” being changed to “/u/” now? What if you change your code to use “/u/” instead, does it work?

10 Likes

That was it. Many thanks!

3 Likes