Search code examples
scala.jsscalajs-react

Setting state in ajax success in scalajs-react


I am trying to open one popup on successful submission of another in scalajs-react. My problem is on success state is not getting modified. Here is my addNewAgent method called as a callback on submission of first popup.

def addNewAgent(userModel: UserModel, addNewAgent: Boolean = false): Callback = {
  println(addNewAgent)
  if(addNewAgent){
    createUser(userModel).onComplete {
      case Success(s) =>
        println(s.msgType)
        if (s.msgType == ApiResponseMsg.CreateUserWaiting){
          t.modState(s => s.copy(showNewAgentForm = false, showConfirmAccountCreation = true))
        } else {
          t.modState(s => s.copy(showNewAgentForm = false, showRegistrationFailed = true))
        }
      case Failure(s) =>
        println(s)
        t.modState(s => s.copy(showRegistrationFailed = true))
      // now you need to refresh the UI
    }
    t.modState(s => s.copy(showNewAgentForm = false))
  } else {
    t.modState(s => s.copy(showNewAgentForm = false))
  }
}

and component code is :

val component = ReactComponentB[Props]("AddNewAgent")
.initialState(State()) // initial state from TodoStore
.backend(new Backend(_))
.renderPS(($, P, S) => {
  val B = $.backend
  <.div()(
    Button(Button.Props(B.addNewAgentForm(), CommonStyle.default, Seq(HeaderCSS.Style.SignUpBtn)),"Sign Up"),
     if (S.showNewAgentForm) NewAgentForm(NewAgentForm.Props(B.addNewAgent))        
    else   if (S.showConfirmAccountCreation  ) ConfirmAccountCreation(ConfirmAccountCreation.Props(B.confirmAccountCreation))

      else
      Seq.empty[ReactElement]
  )
})
//  .componentDidMount(scope => scope.backend.mounted(scope.props))
.configure(OnUnmount.install)
.build
def apply(props: Props) = component(props)

Solution

  • For anyone looking for an answer to this problem what is happening here is that the modState calls inside the future completion will never be really called because they return a Callback that don't run. To solve this you need to add runNow() like t.modState(s => s.copy(showNewAgentForm = false, showRegistrationFailed = true)).runNow()