Make an api write a post request to a file - node.js

I wandered if there is a way to make a browser make a post request to an api who then appends that message to a file ? If so how would I do this

You can use the built-in method fetch.
So for example you want to make a request to http://localhost:3000/test with the body testing you can write it like this:
fetch("http://localhost:3000/test", { method: 'POST', data: 'testing' })
.then(results => results.json())
.then(res => { /* Do whatever you want with the response */ });
You can read more about this method here: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch

Related

How do I perform an axios put request in nodejs with the request body transformed?

I want the endpoint to have access to an extra field in request object called userData. I could do it with get request like this :
axios.get(`${this.appConfig.getUrlProperties().core}v1.0/address/`,
{ data: req.userData })
But I can't seem to do it with put request in the same manner.
axios.put(`${this.appConfig.getUrlProperties().core}v1.0/address/default/${req.body.address}`,{},
{ data: req.userData })
Looks like you have swapped the config object and payload object. You can try this instead.
axios.put(`${this.appConfig.getUrlProperties().core}v1.0/address/default/${req.body.address}`,
{ data: req.userData }, {})

Body of a request is empty [duplicate]

I have a React application where I am changing POST method to GET with the request body as it is. It works fine with POST request however when I change the method to GET, it gives me error-
message: "org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public
My Front End Code-
export const setData = (getData) => dispatch => {
axios({
method: 'GET',
url: 'http://localhost:8080/api',
headers: {
'Content-Type': 'application/json'
},
data: getData
})
.then (response => {
dispatch({
type: API_DATA,
payload: response.data
})
dispatch({
type: SET_SEARCH_LOADER,
payload: false
})
})
.catch(function(error) {
})
}
Can someone let me know what I am missing here. As per my understanding, http allows to have a request body for GET method.
As per my understanding, http allows to have a request body for GET method.
While this is technically true (although it may be more accurate to say that it just doesn't explicitly disallow it), it's a very odd thing to do, and most systems do not expect GET requests to have bodies.
Consequently, plenty of libraries will not handle this.
The documentation for Axois says:
// `data` is the data to be sent as the request body
// Only applicable for request methods 'PUT', 'POST', and 'PATCH'
Under the hood, if you run Axios client side in a web browser, it will use XMLHttpRequest. If you look at the specification for that it says:
client . send([body = null])
Initiates the request. The body argument provides the request body, if any, and is ignored if the request method is GET or HEAD.
If you want to send parameters with get request in axios, you should send parameters as params.
If you want to set "Content-type":"application/json" and send params with get request, you should also send an empty data object.
For example:
const AUTH_TOKEN = 'Bearer token'
const config = {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': AUTH_TOKEN,
},
data: {},
params: {
"post_id": 1
}
}
axios.get("http://localhost/api/v1/posts/", config)
This is not axios, the error origniates from the java backend you're talking to. The public field in your request body is missing.
If you just want to send the data as parameters (which would be odd), pass it using params instead of data (as shown here: https://github.com/axios/axios#example).
I personally don't think your API should support GET with a request body (talk to the devs and ask for documentation).

How to append a JSON descriptor to res.sendFile() in Express?

After passport authenticating success i want to pass the req.user data to the component
using res.sendFile().
I found this answer Here
But i don't know how to read the options param on the component in componentDidMount()
Can any one help me ?
There is no standard way to send mixed JSON + file content by using just the sendFile() method. As a workaround, you can send your JSON data as a custom response header:
const options = {
headers: {
'Access-Control-Expose-Headers': 'User',
'User': JSON.stringify(req.user),
}
};
res.sendFile(path.join(__dirname, '../assets', 'index.html'), options);
Note that the Access-Control-Expose-Headers header is required, in order for your client to always be able to access the extra header.
Then, assuming you are using axios on the frontend:
axios.get(YOUR_URL, response => {
const user = JSON.parse(response.headers['User']);
console.log('User Object', user);
});
With fetch:
response.headers.get('User');

Access an API via Node.js

Using the sample Python code provided by the Bureau of Labor Statistics I was able to successfully access their API and print the JSON containing the data series in the console. Python code below:
#BLS query.
headers = {'Content-type': 'application/json'}
data = json.dumps({"seriesid": ['CES0000000001'],"startyear":"2010", "endyear":"2019"})
result = requests.post('https://api.bls.gov/publicAPI/v2/timeseries/data/', data=data, headers=headers)
print(result.text)
While the Python code works just fine, I would prefer to use JS, but have been unsuccessful in doing so. I have tried using fetch, but I am not making any progress. See JS code below:
fetch('https://api.bls.gov/publicAPI/v2/timeseries/data/', {
method: 'POST',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({seriesid: ['CES0000000001'], startyear:"2010", endyear:"2019"})
})
.then(function(response) {response.json()})
.then(function(json) {console.log(json)});
I am sure I am messing up something simple here, but I'm at a loss. Any help would be greatly appreciated. For reference, additional info from the BLS on their API can be found at this link:
https://www.bls.gov/developers/api_signature_v2.htm
Try using this,
const data = { username: 'example' };
fetch('https://api.bls.gov/publicAPI/v2/timeseries/data', {
method: 'POST', // or 'PUT'
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then((response) => response.json())
.then((data) => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
But what I think the real problem might be that you are using an API which has authentication used, so make sure that you are using the api key along with the post req itself.
if you can have the api documentation, please refer it and see how to make a authenticated request to the server.
If you want to use regular JavaScript's fetch in Node.js, it won’t work, One reason for that is because, NodeJs doesn't make requests via the browser, but Fetch API was made to make requests via the browser
You’d have to use a package called node-fetch, it's just like the regular fetch, but for NodeJs.
You can get it here -> https://www.npmjs.com/package/node-fetch
or you can also use the standard NodeJS HTTP package.
or packages like axios or request to make HTTP requests in NodeJS

NodeJS render a view from AJAX call

I trying to render a view using an AJAX call:
let data = {}
data.ph_user = ph_user
data.nav_destination ='bids_review'
$.ajax({
type: 'POST',
data: JSON.stringify(data),
contentType: 'application/json',
url: '/users/navigation',
});
The router's code is:
router.post('/navigation', (req, res) => {
try {
var fname = req.body['ph_user']
var main_block = req.body['nav_destination']
if(main_block='bids_review'){
console.log(fname, main_block, 'zzzz')
res.render('bids_review', {ph_user: fname, main_block: 'dashboard'});
}
}catch(err){
console.log(err)
}
})
It looks like route is called properly but new view is not rendered. I don't get any errors on either server or client side.
I know i can do via form but would like to know if there is a way to accomplish this with AJAX call. Any guidance is greatly appreciated.
Your route returns rendered HTML to the AJAX call. If you want to render HTML directly from the server, do not use AJAX, just redirect to the route (i.e. use a form to post the data, or change the route to .get and redirect to the location).
To keep using AJAX, you probably want to return JSON from the route, and render it on the client.
I had the same problem. I did an Ajax call for modifying data. After the update the partial page had to be displayed again but now with information that the data has been updated. The code is just sample code but the important part is in the response the response.body is a stream. If you stream that to the partial (innerHTML), then your page is updated with the res.render data. Extra note: you could put that code in a separate function and then you could work with PUG with partials too :-)
// get form data, save history and post data to database
await this.serializeForm(form)
.then(data =>
this.replaceState(form.action).then( () =>
fetch(form.action, {
method: "POST",
headers: { 'x-requested-with': 'XMLHttpRequest',
"Content-Type": "application/json" },
body: JSON.stringify(data)
}).then( (response) =>
response
.body
.getReader()
.read()
.then( ({value}) => {
let html = new TextDecoder('utf-8').decode(value);
this.partialPage.innerHTML = html;
})
)));

Resources