3

I had a monolithic application, in which window.location.href was working as according to what I needed. But now I changed my application to microservices architecture. So, API is running on a separate server while UI is on another server.

Now for my xhtml file, I have a commandButton in my employeelist.xhtml.

How do I stop my oncomplete process windows redirect if there is an error (API is down / or any other errors)?

Currently, it logs the errors but FaceMessages are not displayed and also, the page is redirected to employee_details.xhtml but there are no details in that page as onEmployeeSelect method throws an error.

  <p:commandButton value="#{employee.employeeId}">
    <p:ajax process="@this" listener="#{employeeBean.onEmployeeSelect(employee)}" 
   oncomplete="window.location.href='employee_details.xhtml'" />
</p:commandButton>

Backingbean is

public void onEmployeeSelect(EmployeeDefinition employeeVO) {
   try{
         //calls API
        if (success) {
          //show employee details
        }
    }
    catch(Exception ex){
       //if API is not reachable
        addMessage(FacesMessage.SEVERITY_ERROR, ERROR, ex.getMessage());
    }

}

New to JSF/Java, any help would be appreciated.

rhonda
  • 99
  • 2
  • 6
  • I would use something like [this](https://stackoverflow.com/questions/14401652/how-to-trigger-args-validationfailed-in-primefaces-oncomplete) – WoAiNii May 23 '20 at 13:52
  • I was trying to understand the concept of JSF validations as provided in the [link](https://stackoverflow.com/questions/14401652/how-to-trigger-args-validationfailed-in-primefaces-oncomplete). But it looks like JSF validations occur on input data [from another question](https://stackoverflow.com/questions/9474151/isvalidationfailed-default-value) or this [link](https://www.tutorialspoint.com/jsf/jsf_validation_tags.htm). But in my case, error is from the backing bean and oncomplete doesn't listen to any input to validate. – rhonda May 23 '20 at 17:00
  • 1
    Maybe [this](https://stackoverflow.com/questions/30190214/how-to-use-el-in-primefaces-oncomplete-attribute-which-is-updated-during-action) explains better a way to manage your scenario: in your catch put a variable into args, as described there, and check it in the oncomplete method, to execute the redirect only if that is not defined. In that page there's also another possible solution, moving oncomplete logic in your controller. – WoAiNii May 23 '20 at 17:24
  • Primefaces Request context is deprecated. [link](https://stackoverflow.com/questions/55285566/primefaces-requestcontext-under-7-0/55285760) says to use `PrimeFaces.current().executeScript()` So in my scenario catch block returns some random argument. oncomplete in xhtml has `oncomplete="resizeComplete(args.result)"` and `resizeComplete()` is javascript method. Can you provide me an example code for my scenario? – rhonda May 23 '20 at 17:56

1 Answers1

3

Solution 1:

Base logic: move oncomplete logic into your controller

<h:form>
    <p:growl id="growl" />
    <p:commandButton process="@this" value="#{employee.employeeId}" update="growl"
        action="#{employeeBean.onEmployeeSelect(employee)}" />
</h:form>

...

public void onEmployeeSelect(EmployeeDefinition employeeVO) {
    try {
        // calls API
        PrimeFaces.current().executeScript("window.location.href='employee_details.xhtml'");
    } catch (Exception ex) {
        // if API is not reachable
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", ex.getMessage()));
    }
}

Solution 2:

Base logic: use validation exception logic

<h:form>
    <p:growl id="growl" />
    <p:commandButton process="@this" value="#{employee.employeeId}" update="growl"
        action="#{employeeBean.onEmployeeSelect(employee)}" oncomplete="if (!args.validationFailed) window.location.href='employee_details.xhtml'" />
</h:form>

...

public void onEmployeeSelect(EmployeeDefinition employeeVO) {
        try {
            // calls API
//          int i=1/0;

        } catch (Exception ex) {
            // if API is not reachable
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", ex.getMessage()));
            FacesContext.getCurrentInstance().validationFailed();
        }
    }

Solution 3:

Base logic: pass parameter from controller to page

<h:form>
    <p:growl id="growl" />
    <p:commandButton process="@this" value="#{employee.employeeId}" update="growl"
        action="#{employeeBean.onEmployeeSelect(employee)}" oncomplete="if (args.rhonda) window.location.href='employee_details.xhtml'" />
</h:form>

...

public void onEmployeeSelect(EmployeeDefinition employeeVO) {
    try {
        // calls API
        int i=1/0;

        PrimeFaces.current().ajax().addCallbackParam("rhonda", "rhonda");

    } catch (Exception ex) {
        // if API is not reachable
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", ex.getMessage()));
    }
}

Depends on Primefaces version, the code should change, but the base idea remains.

WoAiNii
  • 1,003
  • 1
  • 11
  • 19
  • Thank you so much @WoAiNii!!!! Solution 2 worked :) Although, I had to use `listener` instead of `action` . But that worked – rhonda May 23 '20 at 20:29