jsfhttp-redirectprimefacesajax-polling

Refresh/Redirect from backing bean when p:poll reaches certain condition


I'm implementing an auction system using jsf.

in the item page, I have a countdown showing how much time is left for this sale. I show it with <p:outputlabel value=#{itemBean.timeToEnd()} />.

the timeToEnd() method returns a string in the format: 1 days, 2 hours.. etc. it calculates it on a Date object inside that bean. I update the label with <p:poll>, on a 1 second interval.

my problem is, that when counter reaches 0 seconds, I want to refresh the whole page, where it will show that the sale is inactive.

in timeToEnd(), I added a logic that if the end date is passed, or seconds to end is 0, then execute the following code that suppose to refresh the page:

ExternalContext ec1 =FacesContext.getCurrentInstance().getExternalContext();             
ec.redirect(((HttpServletRequest) ec.getRequest()).getRequestURI());

But it doesn't refresh the page. I think it doesn't refresh since the page is "live" for some time. (user is on item page from a time where sale was active).

any ideas on how this could be implemented?

P.S I also tried to implement this countdown on client level, when I store the end date with c:set and then use javascript or something for the view update. but then I noticed that also for the code

 <c:set var = "enddate" value = "#{itemsBean.endDate}" scope="session"  />

for every use of "enddate" the server is called, rather than storing the date locally and then perform the calculation without bothering the server. so I didn't even get to the javascript part. if there's a way to implement locally, would be happy to hear about it.


Solution

  • Never do business/controller logic in a getter method. Also not if that getter represents EL 2.2 direct method invocation. It's after all still a value expression which is only evaluated during generating the HTML output and writing the response body during render response phase. That moment is clearly too late to set a response header (to instruct the client to perform a redirect).

    Move that logic to an action(listener) method.

    <p:poll ... listener="#{bean.onpoll}" />
    
    public void onpoll() {
        // ...
    
        if (someCondition) {
            redirect();
        }
    }