Tips for retaining items in JSF Flash Scope after an Ajax request or page refresh

I am currently working on a complex project that involves a large table and numerous relations. To manage this, my form includes multiple tabs, dialogs, and PrimeFaces commandButtons for CRUD operations using Ajax requests.

The structure of the xhtml file looks something like this:

<ui:define name="content">
<h:body>
    <p:growl id="growl"/>
    <h:form id="formCars" enctype="multipart/form-data">
        <p:tabView id="formTabView" scrollable="true" >
            <p:tab title="Tab1">
                <ui:include src="tabOne/tabOne.xhtml" />
            </p:tab>
            <p:tab title="Tab2">...</p:tab>
            ...
            <p:tab title="Tab8">...</p:tab>
        </p:tabView>
        <br />
        <div align="center">
            <p:commandButton id="cmdSave" value="Save" 
                action="#{controllerMB.save}" icon="ui-icon-disk" 
                update="@form :growl" process="@form @this" validateClient="true" />
        </div>
    </h:form>

    <p:dialog header="Car Color" id="modalCarColor" widgetVar="modalCarColor" appendToBody="true" modal="true" height="500" width="700" dynamic="true" closeOnEscape="true" >
        <p:ajax event="close" listener="#{controllerMB.closeModalCarColor}" update="@this,:formCarColor"/>
        <h:form id="formCarColor">
            <ui:include src="tabTwo/carColor/carColor.xhtml" />
        </h:form>
    </p:dialog>

    <p:dialog header="Car Size" ...>
        <p:ajax event="close" .../>
        <h:form id="formCarColor">...</h:form>
    </p:dialog>

</h:body>
</ui:define>

Everything works perfectly fine, however I have encountered an issue when attempting to reload the page. While I am able to maintain the main object in the flash using

FacesContext.getCurrentInstance().getExternalContext().getFlash().keep(key)

in the @PostConstruct method of the @ViewScoped controller, if any Ajax request is triggered, the main object stored in the JSF Flash Scope gets lost, preventing me from reloading the page.

My current controller implementation is structured as follows:

@ManagedBean(name="controllerMB")
@ViewScoped
public class ControllerMB implements Serializable{
    
    // PostConstruct method
    @PostConstruct
    public void init(){

        if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
            car = (Car) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("car");
            FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
        }
        if(car==null) { 
            redirect_back();
            return;
        }

        // Initializing attributes and preparing form
    }

    // Other methods
    
}

Is there a solution or workaround available for this issue? Additionally, is it feasible to capture/handle the reload event from the browser with JavaScript to process the form data before the reload?

I am utilizing PrimeFaces 5.3, JSF 2, Maven, Tomcat 7 and Java 7 for this project. Any insights or suggestions would be greatly appreciated.


Edit 1: Upon implementing the solution provided by user NightEagle, although it almost worked, I encountered some issues. I made modifications to the code as follows:

<ui:composition ....>
    <f:metadata>
      <f:event type="preRenderView" listener="#{controllerMB.preRender}"/>
    </f:metadata>
    <ui:define name="title">...</ui:define>
    <ui:define name="header">...</ui:define>
    <ui:define name="content">...</ui:define>
</ui:composition>

and

public void preRender()
{
    System.out.print("PRE-RENDER ");
    if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
        System.out.println("KEEP");
        FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
    } else {
        System.out.println("PUT");
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("car",car);
    }
}

After opening several dialogs, the application started displaying the JSF1095 error. Here is the output after interacting with the UI:

PRE-RENDER PUT
PRE-RENDER KEEP
PRE-RENDER KEEP
Jul 14, 2017 11:43:59 AM com.sun.faces.context.flash.ELFlash setCookie
WARNING: JSF1095: The response was already committed by the time we tried to set the outgoing cookie for the flash.  Any values stored to the flash will not be available on the next request.
PRE-RENDER PUT
Jul 14, 2017 11:44:00 AM com.sun.faces.context.flash.ELFlash setCookie
WARNING: JSF1095: The response was already committed by the time we tried to set the outgoing cookie for the flash.  Any values stored to the flash will not be available on the next request.
PRE-RENDER PUT
Jul 14, 2017 11:44:04 AM com.sun.faces.context.flash.ELFlash setCookie
WARNING: JSF1095: The response was already committed by the time we tried to set the outgoing cookie for the flash.  Any values stored to the flash will not be available on the next request.

Your assistance in finding a suitable solution would be greatly appreciated. Thank you in advance.

Answer №1

I have found a solution that worked for me in my project.

<f:metadata>
  <f:event type="preRenderView" listener="#{myBean.preRender}"/>
</f:metadata>

This is the code for the backing bean:

public class MyBean
{
    @PostConstruct
    public void init(){
        if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
            car = (Car) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("car");
            FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
        }
    }

    public void preRender()
    {
        if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
            FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
        }
    }
}

"The preRenderView event is invoked on every HTTP request (yes, this also includes ajax requests!)." (c)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Getting the UTC time using JavaScript's new Date() method

Despite my thorough search, I have been unable to find a satisfactory solution. My requirement is to obtain the current time in UTC and then subtract a specified number of days (let's say 2 days). For instance, if today is March 25th, I want to retrie ...

Is the express.json() middleware for parsing JSON request body designed to handle synchronous calls?

According to Express.js's documentation, it is recommended to avoid using synchronous functions as much as possible. This is because in high-traffic websites, the accumulation of synchronous calls can negatively impact the performance of the applicati ...

What is the best way to calculate the product of decimal numbers within a TypeScript Number variable?

Imagine you have a number, for example 288.65, and you want to multiply it without the decimal point in order to obtain the result of 28865. However, when attempting to achieve this by using console.log(288.65 * 100), the output is not as expected, showin ...

Developing an interactive website utilizing AngularJS, WCF Service, and SQL Server

Exploring the possibilities of creating a web application, I stumbled upon AngularJS. With plans to incorporate WCF Service and SQL Server into my project, I am intrigued by what these technologies can offer. I want to ensure that AngularJS aligns with my ...

What is the best method for implementing multiple select options in ReactJS?

Hey there! I'm new to React and I'm attempting to create a multiple select option using the Axios GET method. However, I've encountered an issue with adding multiple select options in this file. I've been trying to achieve this with che ...

Exploring the World of AJAX with CodeIgniter

I've been on the hunt for a solid working example of using AJAX with Codeigniter, but most resources I've found are outdated. As an AJAX beginner, I'm struggling to find up-to-date tutorials. What I'm aiming for is an input form on a w ...

Using Javascript to Retrieve "Images" from the "Resources" Directory

I typically use Google Chrome as my browser of choice. Unfortunately, the images on certain websites are causing lagging issues. I am looking for a solution to access and clean up these problematic images in order to improve browsing performance. ...

Transforming a class component into a functional component using React for a session

While working on a React application, I encountered the need for auto logout functionality for inactive users. After referring to this resource, I attempted to convert my class component code to functional components. However, I faced issues as the functio ...

Uploading videos to a single YouTube channel using the YouTube Data API

I have been tasked with creating a node js app for a select group of individuals who need to upload videos. However, our budget is quite limited and we are unable to afford cloud storage services. I am curious if it would be feasible to create a key syste ...

Incorporate an HTML code string into an Angular 2 template

I am working with HTML code stored in a Component variable, shown below: import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: `Hi <div [innerHTML]="name"></div>`, styleUrls: [' ...

The code for the Express app.get() method on the server is not being updated, although other parts of the

Recently, I encountered an issue with my node js and express server that is running on localhost. I made a change in the server code from: app.get('/', (req, res) => { res.sendFile(__dirname + '/public/index.html'); }); To: app. ...

Issue encountered when trying to insert an array in JavaScript into MongoDB using Mongoose

I am currently learning about node.js and mongodb. I attempted to insert a JavaScript array variable into mongodb using mongoose, but encountered an error. Upon running this code, I received the following error message: ValidationError: CastError: Cast t ...

Encountering the error code 'ERR_EMPTY_RESPONSE' while utilizing an AJAX-powered live search feature

My website features a live AJAX search bar that retrieves records from a MySQL database. However, when users repeatedly conduct searches by modifying the search criteria, some web browsers display an error message stating 'ERR_EMPTY_RESPONSE'. ...

How can I hide elements "100, 4, 9, 14" in AngularJs?

In my project, the red number div is a button, and I need to hide the numbers 100, 4, 9, and 14 when the button can be clicked, so I am using "display none" instead of "opacity:0". How can I determine the number 100 div and hide it? I am unsure how to uti ...

What is the best way to display a jQuery UI dialog when the page is reloaded?

I am trying to display a jQuery UI dialog when the user tries to reload or close the browser. Here is my code snippet: $(window).bind('beforeunload', function () { $("#confirm").dialog({ width: 500, modal: true, buttons: { ...

Transforming the output byte array into a Blob results in file corruption

I am currently developing an Add-in for Word using Angular and the Office Javascript API. My goal is to retrieve a Word document through the API, convert it to a file, and then upload it to a server via POST method. The code I have implemented closely re ...

Suggestions for rearranging the sequence of watchers in AngularJS?

After creating a controller and directive with local scope, I added a watcher on a scope variable in the postLink method and implemented $interval to change the variable. Additionally, I included a watcher on the binded variable in the controller. console ...

Steps to insert a button onto the Gmail compose toolbar using a Chrome extension

Exploring the realm of Chrome extensions, I am endeavoring to integrate a button into Gmail's compose bar akin to this example. Despite experimenting with various Gmail APIs, I have yet to discover a suitable solution. If anyone has insights on how to ...

Tips for adjusting collisions between models using three.js and oimo.js

I am currently working on implementing collision with an object using three.js by importing a model and then creating a body in Oimo to represent it. My problem arises from the fact that the center of the model does not align with the center of the object ...

Learn the process of uploading a file using FormData alongside multer in node js. Experience the issue of receiving undefined in req.file and { } in req.body

Is there a way to successfully upload a file using FormData along with multer in Node.js? I seem to be encountering issues as req.file shows undefined and req.body displays {}. Check out the HTML code snippet below: <input type="file" name=&q ...