switch to new page on form submit react - node.js

I have this (in my contact.js file).
axios
.post('http://localhost:3000/create', book)
.then(() => console.log('Created'))
.then(() => this.props.history.push({Home}))
.catch(err => {
console.error(err);
});
It calls this successfully, but now I want to render a new page, which would be home.js, in the same folder. I was wondering how I can do this, after it makes the call to the backend. Can I do it from the front end, or does it have to be backend?

If the url location of your home.js page is '/home', you can trigger a refresh of the page with the history.pushState method.
Though, you router descending from your React framework may have some implemented method to accomplish this task too. Keep in mind that the history API is access to to the navigator history, allowing you to trigger render of a previous page, a refresh, etc..
You access to the history API by the DOM Window object, for instance a call to the pushState method should look like :
window.history.pushState(null, "", "/Home");
Otherwise you can also use the location API from the BOM object
location.assign('/Home');
which is similar to the window.history.pushState method
https://www.javascripttutorial.net/javascript-bom/javascript-redirect/

Related

How can i write a function to call(POST) an API, from within the web server and not the browser. -NextJS

How can i write a function to call an API, from web server to API within the server itself.
I do not want the browser to know that he is calling an API or and information about the API, even the link.
The API call(POST method) should be executed on the server.
Using Nextjs with axios.
I also want the function to be a component.
If you want to fetch data before loading the page (when the actural page load request happens), use server side rendering.
In Next.js you can use getServerSideProps for doing this. By doing this, you get to keep the api call inside the component, and the sever will fetch the data before rendering your component. Attaching a sample of code that you can refer for this.
export async function getServerSideProps(context) {
return {
props: {}, // will be passed to the page component as props
}
}
For more info, please visit the nextjs official documents. Attaching a link for the above example.
https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props

External web service redirects the user and posts data to my callback URL. How do I render the posted data to the user in an Express/Next.js app?

Any help would be hugely appreciated! Been stuck on this for a few days.
I have an Express/Next.js app where:
I send the user to an external website
user makes a payment
external website redirects and posts data back to my callback URL.
So now I have the user on a mysite.com/payment-complete route but also want to display the data that was sent back.
I have an app.post endpoint to successfully grab the data:
app.post("/payment-complete", async (req, res) => {
const transactionID = req.body.trans_id;
});
How would I pass the data to the user who is already on that route? Or pass the data before the page is rendered?
The flow of data is third party > my server > user and I'm not sure how to make this work.
I'd be grateful for any help/direction with this.
If anyone comes across this - the problem was that in Express (and other languages) you can't redirect or render a view for an AJAX POST request but you can if the POST request is coming from a submitted html form. The web service was in fact POST-ing the data and redirecting my users with a form and so I could render a view.
Following code worked using Handlebars templating engine to send the render.
router.post("/payment-ok", async (req, res) => {
const transactionID = req.body.trans_id;
return res.render("rendertest", { id: transactionID });
});
Should also possibly work with app.render to send a Next.js view instead, but I wanted to render from a separate routes file.

Couldn't Redirecti page after form action submit to node server.(react front)

I'm currently building a web with react, and in this app I'm also building a register functionality, since the user is mainly going to type Chinese in the input tag, I use a form action to submit the form instead of using onChange property in each input (as far as I know, React community haven't found a proper way to deal with the onChange bug when typing Chinese).
And the main problem is that since I'm using the form action to submit the form data, I couldn't get response from the server, and that cause me unable to authenticate and redirect the page.
I would like to know whether there is something wrong with my logic or how to solve this problem by code, thank you;.
I tried using "redirect" in the backend, it works partially, by partially I mean that I couldn't receive response in the front end because I used a form action to submit instead of fetch or axios, so that I don't know how to authenticate in this case.
Front End using React
<form action='http://localhost:8000/' method='post'>
.....</form>
Back End Using Node with Express
db.collection('memberProfiles').insertOne(userModel)
.then(response => {res.redirect('http://localhost:3000/memberProfile').send('token');})
.catch(err => res.send('Page ERROR'));
client.close();

Redirect from React to an Express route from my API server on the same domain

I have both a React APP and a Express API server on the same server/domain. Nginx is serving the React APP and proxying the express server to /api.
Nginx configuration
https://gist.github.com/dvriv/f4cff6e07fe6f0f241a9f57febd922bb
(Right now I am using the IP directly instead of a domain)
From the React APP, when the user does something I want him to download a file. I used a express route on my API server that serve the file. This works fine when the user put the URL.
This is my express route:
donwloadFile.route('/')
.get((req, res) => {
const file = '/tmp/PASOP180901.txt';
res.download(file);
});
This is my react redirect:
if (this.state.downloadFile === true) {
this.setState({ downloadFile: false });
setTimeout(() => {
window.location.href = '/api/downloadFile';
}, 100);
}
The address changes but the download don't start. If I press F5 then the download starts just fine. If I use a external URL to host my file, the download start just fine too.
Thanks
First things first. Don't use setTimeout, but rather use the callback function of setState to execute code after the state is set ensuring it has been modified. Calling the callback function will guarantee the state is changed before that code in the callback is executed.
from the official docs:
setState() enqueues changes to the component state and tells React
that this component and its children need to be re-rendered with the
updated state. This is the primary method you use to update the user
interface in response to event handlers and server responses.
setState() does not always immediately update the component. It may
batch or defer the update until later. This makes reading this.state
right after calling setState() a potential pitfall. Instead, use
componentDidUpdate or a setState callback (setState(updater,
callback)), either of which are guaranteed to fire after the update
has been applied.
setState(stateChange[, callback])
The second parameter to setState() is an optional callback function
that will be executed once setState is completed and the component is
re-rendered. Generally we recommend using componentDidUpdate() for
such logic instead.
So, instead of:
if (this.state.downloadFile === true) {
this.setState({ downloadFile: false });
setTimeout(() => {
// execute code, or redirect, or whatever
}, 100);
}
you should do:
if (this.state.downloadFile === true) {
this.setState({ downloadFile: false }, () => {
// execute code, or redirect, or whatever
});
}
Now, for your specific problem
Set headers in your server side
You can set the Content-Disposition header to tell the browser to download the attachment:
from here:
In a regular HTTP response, the Content-Disposition response header is
a header indicating if the content is expected to be displayed inline
in the browser, that is, as a Web page or as part of a Web page, or as
an attachment, that is downloaded and saved locally.
Set it like this:
('Content-Disposition: attachment; filename="/tmp/PASOP180901.txt"');
Force download from the client
There are multiple ways to force the download from the client, but this is the only one I've tried.
For this to work, you have to have the content of text somehow in the client (your express route can return it for example) and create a filename for the file that will be downloaded.
let element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
Basically you are creating an empty link component, setting the data attribute to it with the text's content, attaching the link to the body, clicking the link and then removing the link from the body.
Open the link in a new tab
Opening the link in a new tab will trigger the download as well:
window.open('/api/downloadFile');
Redirect programatically
Have a look at this question in SO
You can do this:
this.props.history.push("/api/downloadFile")?
If cannot access this.props.history you can import { withRouter } from 'react-router-dom'; and export default withRouter(yourComponent); to access it.

jQuery-File-Upload(Blueimp) with custom ajax under October CMS

Trying to create a component under October CMS which should allow frontend multiple fileuploads. I try to integrate in already exiting form the Blueimp jQuery-File-Upload Plugin and because October CMS uses an integrated ajax Framework which allows data Submission to Component method I would use this ajax method instead what from default by Blueimp
so a normal fileupload looks like
$('#gallery').fileupload({
// Uncomment the following to send cross-domain cookies:
//xhrFields: {withCredentials: true},
url: 'path/to/controller'
});
but instead I would like to use something like
$('#gallery').fileupload({
// Uncomment the following to send cross-domain cookies:
//xhrFields: {withCredentials: true},
add: function (e, data) {
data.submit();
$.request('onUploads', {
success: function(data){
console.log(data);
}
})
}
});
You need to use the Request class from Laravel which OctoberCMS sits on top of. Basically you go to the code section of your layout file and add
function onUploads()
{
// Get the file
$file = Request::file('somefile');
// Code to do something with it
// enter code here
}
Based on what you are trying to achieve you can write appropriate code to upload it. For example, in my Social Login plugin i use methods of this class to fetch photos from the chosen Social network and create a relation between the plugin's Social model and the uploaded file so that a frontend user may output the photo as a display photo in their web app.
Another good way to do it would be to directly upload it into the themes directory by doing something like Request::file('somefile')->move(app_path() . '/themes/yourtheme/assets/uploads/'); but then you will need to add code to limit the upload size and also to fix the file names. Feel free to make a comment if you need help on achieving something particularly. gl hf

Resources