Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Forcing interceptRender even when routing to the current router #107

Closed
ramnivas opened this issue Apr 22, 2015 · 3 comments
Closed

Forcing interceptRender even when routing to the current router #107

ramnivas opened this issue Apr 22, 2015 · 3 comments

Comments

@ramnivas
Copy link
Contributor

Context: #100 and #103

When I redirect to the current url (i.e. redirect url == the current url), I will like to have interceptRender to still be called. This will helps me, for example, show a different menu based on the application state (authentication in my case) even though the url is the same (many sites such as github.com do the same).

Here is a minimalist example. Is there a way to force router to flow through interceptRender or any suggestion for an alternative pattern to achieve the same thing?

package example

import japgolly.scalajs.react.extra.router.{BaseUrl, Redirect, RoutingRules}

import scala.scalajs.js
import js.annotation.JSExport
import org.scalajs.dom

import scala.scalajs.js

import japgolly.scalajs.react._
import vdom.all._

@JSExport("Main")
object ScalaJSReactExample extends js.JSApp {
  def main(): Unit = {
    val baseUrl = BaseUrl.fromWindowOrigin + "/"

    val router = MainRouter.router(baseUrl)

    React.render(router(), dom.document.body)
  }
}

object MainRouter extends RoutingRules {
  val root = register(rootLocation(LandingPage.Component(())))

  override protected val notFound = redirect(root, Redirect.Replace)

  register(removeTrailingSlashes)

  override protected def interceptRender(ic: InterceptionR): ReactElement = {
    println(s"Intercepting... ${AuthenticationStore.authenticated}")
    if (AuthenticationStore.authenticated) {
      div(
        div(
          button(onClick --> {println("Logging out"); AuthenticationStore.authenticated = false; ic.router.setIO(root).unsafePerformIO()})("Logout")
        ),
        ic.element
      )
    } else {
      div(
        div(
          button(onClick --> {println("Logging in"); AuthenticationStore.authenticated = true; ic.router.setIO(root).unsafePerformIO()})("Login")
        ),
        ic.element
      )
    }
  }
}

object AuthenticationStore {
  var authenticated = true
}

object LandingPage {
  val Component = ReactComponentB[Unit]("Landing").render{ _ =>
    println(AuthenticationStore.authenticated)
    if (AuthenticationStore.authenticated) {
      PrivatePage.Component(())
    } else {
      PublicPage.Component(())
    }
  }.build
}

object PublicPage {
  val Component = ReactComponentB[Unit]("Public").render(_ => div("Public")).build
}

object PrivatePage {
  val Component = ReactComponentB[Unit]("Private").render(_ => div("Private")).build
}
@japgolly
Copy link
Owner

Another stateful router issue... The current router isn't designed to be stateful. I have long been of the mind that the router should route, and state should be managed elsewhere by the developer. The two shouldn't be conflated.

Then I was thinking about your case. In your case the reality is that a single URL presents more than one UI based on some state. It sounds like I'm just repeating the first paragraph but I'm not. We aren't conflating concepts (which was my aversion). State is part of the real-world-model of routes, not just the automated-world-system or even automated-world-model.

Ok. Accommodation of state needs to be built in the router. Not a task for today. Until the next release I suggest you just look at the source code (it's not complicated) find a way or a hack. It will be temporary.

@japgolly
Copy link
Owner

@ramnivas Let me close this mate. I'll work on this in #103.

@ramnivas
Copy link
Contributor Author

Thanks. Looking forward to the approach you take for #103

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants