Reputation: 3273
In wordpress I am clicking a search button in front-page.php
, that calls a result page . front-page.php
loads FrontPage.js
, which has this:
localStorage.clear();
localStorage.setItem('flightCardsDataArray', JSON.stringify(flightCardsDataArray));
isDataLoaded();
window.postMessage({ type: 'flightCardsDataLoaded', data: flightCardsDataArray }, '*');
I would like to read this message in App.js
, which is React code and this react code insert cards on result page . In App.js
I am doing this
window.addEventListener('message', (event) => {
if (event.data && event.data.type === 'flightCardsDataLoaded') {
// Data has been sent from the search page
const data = event.data.data;
console.log('flightCardsDataArray - from app', data);
}
});
but it always gives me data
, which is associated with the previous search. I would like to get data for the current search (latest click on search button of front-page.php
) .
UPDATE
As per suggestion below , I set the debugger and see that correct iteration of data is passed in flightCardsDataArray
when I set it in localstorage
, however I am still not able to figure out why App.js
shows previously passed data.
My guess is that App.js
is reading the message even before the latest click happens , but how do I resolve this? Or is there any other way to approach this?
Upvotes: 1
Views: 261
Reputation: 3273
I changed the approach and made the API call in React itself. So , when the button is clicked in front-page.php
, it goes to result page.php
which is rendered by React . So I made the call to API in React just before rendering hence eliminating the need for event listeners to listen from one page to another to transfer data.
The data that needs to be passed from front-page.php
to result page.php
and do not require event listeners can still be passed using localStorage.setItem
and get it in react using localStorage.getItem . Here is what I am doing in react application which includes fetching and parsing data
const CreateApp = (props) => {
//use useState (https://react.dev/reference/react/useState) for handling asynchronous behavior
const [card, setCard] = useState([]);
const [cardLoaded, setCardLoaded] = useState(false);
const fetchCardData = async () => {
try {
const options = {
method: 'GET',
url: 'https://yourapi.com/method',
params: {
param1: '1',
param2: localStorage.getItem('param2'),
param3: localStorage.getItem('param3'),
},
headers: {
'content-type': 'application/octet-stream',
'Some-Key': 'abc',
'Some-Host': 'yourapi.com'
}
};
const response = await axios.request(options);
//parse response
return parsedResponse ;
} catch (error) {
console.error('Error occurred while parsing , error);
return { success: false };
}
}
//useEffect for rendering with asynchronous response (https://react.dev/reference/react/useEffect#useeffect)
useEffect(() => {
// Call the fetchCardData function to fetch data
fetchCardData()
.then((parsedResponse) => {
// Now you have the parsedResponse, you can set it in your state or use it as needed
setCard(parsedResponse);
setCardLoaded(true);
})
.catch((error) => {
console.error('Error occurred while fetching data:', error);
});
}, []);
if (!cardLoaded) {
return <p>Loading...</p>;
}
//render with data
const columns = card.map((item, index) => {
return(
<div className="col-lg-4 responsive-column">
....
....
</div>
);
});
return <>{columns}</>;
}
export default CreateApp;
Upvotes: 0