Nuxt 3 re render component after API response - components

I am working on nuxt 3 and I need re render component after API response.
<template>
<AssetsTab
:form-data="formData.assets"
:loader="loader"
#on-submit="submitForm"
/>
</template>
<script setup>
onMounted( async () => {
await getDetails(); //API call
});
</script>
Here once the API call getDetails() successed. I need to rerender AssetsTab component again.

Use a reactive variable like const isApiRespond = ref(false) and make the variable true in the getDetails function when you get the successful API response. Then in the template use v-if like below,
<AssetsTab
v-if=isApiRespond
:form-data="formData.assets"
:loader="loader"
#on-submit="submitForm"
/>
Now if you again want to Re-Render your component then use a key prop in your component. Whenever your props value update, the component will auto-update.
<AssetsTab
v-if=isApiRespond
:key="rerendervalue"
:form-data="formData.assets"
:loader="loader"
#on-submit="submitForm"
/>
In above code whenever your key value update the whole component will auto update.
Here is a VuePlaygroud Link check it's console you will understand.

Related

passing function between separate components in react not between child and parent

I have a small question regarding passing functions between components that are not in parent/child relationship.
My structure inside App.
function App() {
return (
<div className="App">
<Header/>
<Pfl />
<Sdc/>
<Checkscan/>
</div>
);
}
Those 3 components have an on click function attached to a button i want the button from the pfl component to trigger all 3 on click functions.
When i click on the button in the pfl component i want to trigger the function running in the pfl component and the functions that are inside the Sdc,Checkscan component.
Whats the best way to do it and pass the functions from the other components so when i click the button inside the pfl component it will trigger all the methods from the other 2 components(Sdc,Checkscan)?
Or if I make a container that looks like this
export default function Apicontainer() {
return (
<React.Fragment>
<Pfl />
<Sdc />
<Checkscan />
<Button variant="contained">Start</Button>
</React.Fragment>
)
}
and in app.js i only have the Apicontainer.
How do i transfer all the functions to work in that button click Component
I just wrote some quick and dirty example code to show how you can share things between components via a parent component:
export default function Apicontainer() {
const [sharedState, setSharedState] = useState({sdc: null, checkScan: null})
function pflFunction() {
console.log('pflFunction')
// do your stuff here. I would update state with some reasonable data, and then pass
// the relevant data to the component that needs it. This is just an example.
setSharedState({sdc: 'sdcData', checkScan: 'checkScanData'})
}
return (
<React.Fragment>
<Pfl onClick={pflFunction} />
<Sdc data={sharedState.sdc}/>
<Checkscan data={sharedState.checkScan} />
<Button variant="contained">Start</Button>
</React.Fragment>
)
}
// Example of how to trigger a function inside a component (separate file):
export default function Sdc({data}){
const sdcFunction = useCallback(() => {
// implement the function you want to call here. useCallback makes sure to keep
// a stable reference to the function, so that you can rely on it in a useEffect
}, [])
useEffect(() => {
if(data){
// do something. This effect will run whenever the data or sdcFunction changes.
sdcFunction()
}
}, [data, sdcFunction])
return (
<div>your Sdc view code here</div>
)
}
For the record: If fplFunction is anything else than an onClick handler, you should make sure the function has a stable reference, using useCallback (as in the last component)

POST FORM in node and receive data response back to same webpage

I have a webpage that takes form details, POSTS the data and should then show the results. I'm using express for my routing.
This all works fine by resending the data with the HTML template after the POST but I think there must be a better way by hiding the "results" HTML section then just showing it once the data is known from the form. I've shown a cutdown version of my pages below.
On first load, the page says "your result is undefined", which I would expect but is ugly.
I could remove the "result" section and create a 2nd HTML page to resend from the POST route with it in which would work but I think there must be a better way.
I want to hide the result section on 1st page load then make it appear on the button submit with the result data. I can get the section hide/unhide but I can't get the data results back to display them. On button submit the form results just appear in the weburl www.mywebsite.com/?data almost like a GET request
I have tried using FormData and npm 'form-data' in a POST but can't get it working following these examples https://javascript.info/formdata and https://www.npmjs.com/package/form-data.
My structure in Node is
Router.js file
return res.send(htmlFormTemplate({}));
});
router.post('/css',
[],
async (req, res) => {
let {data} = req.body;
///
result= do some calculation on {data}
///
return res.send(htmlFormTemplate({result}));
});
The htmlFormTemplate is a js file
module.exports = ({result}) => {
return `
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form class="box" method ="POST">
<inputname="data" />
<button>Submit</button>
</form>
<script>
///tried form processing here
</script>
<section id="Results">
<ul><li>Your result is ${result}</li></ul>
</section>
</body>
</html>
`;
};
I'm self-taught and new so hope this makes sense and thanks for any help/ideas
You can check if the result variable is null before it gets to the section div:
${ result === null ? '' :
`<section id="Results">
<ul><li>Your result is ${result}</li></ul>
</section>`}
Like this, it wont show the result div if result if null.
There is a very simple to solve this problem,
just use some templating engine for ex EJS, its very easy to use and will help you better,
and your result is undefined because your using a promise and it might have happened that the response might have not come and you loaded the page. Just use await
return await res.send(htmlFormTemplate({result}));

distinguish between first page load and router <Link />?

i have a route which renders an overlay modal.
i want it to animate-in if i navigate from the UI,
and be loaded as static when navigating from the address bar or after a refresh.
i use nodejs and react + react-router.
i thought about using my universal redux setup to match a state prop for this issue, but maybe there's a much more elegant solution
thanks!
This can be achieved by testing the prevPath property on the props.location object
const [isFirstLoad,setIsFirstLoad] = useState(false)
const {location} = props
useEffect(()=> {
props.prevPath ? setIsFirstLoad(true) : setIsFirstLoad(false)
}, [location])
return <Modal animate={!isFirstLoad}/>
Each render UseEffect will test the props.location (similar to componentWillReceiveProps()) to check if the previous path is different. On load the prevPath property won't exist, so it will be false.

jsf render components with js

Let's say I have
<p:outputPanel/>
What I want to do is to specify rendered attr using js method not serverside.
This is for improving performance.
So I need something like :
<p:outputPanel rendered = "someJsFunction()"/>
What is the solution?
rendered propery is processed at server side and if it resolves to false, the element is not added into the html document. So javascript can't even find the element to display or hide because it is not created.
The only thing you can do is to remove the rendered property and change the display property of the element with javascript.
<div id="myDiv">My Content</div>
<button onclick="myFunction()">Click Me</button>
<script>
function myFunction() {
document.getElementById("myDIV").style.display = "none";
}
</script>
Well, you can have the same effect at page load cause rendered attribute is resolved at Server Side only , So using jQuery you can do it like
$(document).ready(function() {
document.getElementById("YourPanelIdHere").style.display = "none";
});
and it will be not displayed.

How to integrate Stripe "Pay with Card" in backbonejs

I am trying to integrate Stripe "Pay with Card" checkout into backbone Node environment. On the server side, I am using Stripe Node code - that part works good. However, on the client side, I am unable to capture the event.
I would like to capture the submit event from the Stripe popup to call "paymentcharge" method in the view.
Here is my code:
<!-- Stripe Payments Form Template -->
<form id="stripepaymentform" class="paymentformclass">
<script
src="https://checkout.stripe.com/v2/checkout.js" class="stripe-button"
data-key="pk_test_xxxxxxxxxxxxx"
data-amount="0299"
data-name="MyDemo"
data-description="charge for something"
data-image="assets\ico\icon-72.png">
</script>
</form>
Backbone View Class
myprog.PaymentPanelView = Backbone.View.extend({
initialize: function () {
this.render();
},
render: function () {
$(this.el).html(this.template());
return this;
},
events : {
"submit" : "paymentcharge"
},
paymentcharge : function( event) {
this.model.set({stripeToken: stripeToken});
}
});
Backbone Model Class
var PaymentChargeModel = Backbone.Model.extend({
url: function(){
return '/api/paymentcharge';
},
defaults: {
}
})
Setup/Call the View from header menu event
if (!this.paymentPanelView) {
this.paymentPanelView = new PaymentPanelView({model: new PaymentChargeModel()});
}
$('#content').html(this.paymentPanelView.el);
this.paymentPanelView.delegateEvents();
this.selectMenuItem('payment-menu');
I think the problem has to do with your View's el and the event you are listening for.
You never explicitly define your View's el, which means it gets initialized to a detached <div> element. You then use your template to fill that <div> with the form element from the template. Even though your <div> is detached, you get to see the content, because you add the content of you el to #content using jquery.
I think the problem is that you are listening for a submit event on the <div> in your el, not the contained <form>. Try changing your events hash to this:
events: {
'submit form#stripepaymentform': 'paymentcharge'
}
Basically, listen for events on the contained element like in jquery's .on. You can also go right to a button click, something like this:
'click #mysubmitbutton': 'paymentcharge'
Hope this helps!

Resources