NodeJS render a view from AJAX call - node.js

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;
})
)));

Related

Node.js? API Authentication problems

This is what my "dev" sent me. Someone help please
I'm trying my best, but their API doesn't respond to our methods. This authentication is the root of the problem. I'm right now using Axios(the most popular and only method for making API requests for web apps) but it's not accepting request
and then i told him i would ask for help*
You can ask this question- ` How do I make requests for creating order API in my express app? I've tried to make the request by getting my form data from my EJS form using the request.body. But still, it is saying error 400.
Here is his code:
app.post('/order-labels', checkAuthenticated, (req, res) => {
const data = JSON.stringify(req.body);
console.log(data)
const config = {
method: 'post',
url: 'https://labelsupply.io/api/order',
headers: {
'X-Api-Auth': '32854090-03dd-a3c1-Deleted some for safety',
'Content-Type': 'application/x-www-form-urlencoded'
},
data: data
};
axios(config)
.then(function(response) {
console.log(response.data);
})
.catch(function(error) {
console.log(error);
});
})
by console.logging we are getting the data, but the API doesn't accepting
The API Docs are here.
you may need an account to view just put junk
The API calls for url encoded string.
const data = JSON.stringify(req.body);
console.log(data)
data = new URLSearchParams(Object.entries(data)).toString();
console.log(data); // now should be URL encoded
const config = {
method: 'post',
url: 'https://labelsupply.io/api/order',
headers: {
'X-Api-Auth': '32854090-03dd-a3c1-Deleted some for safety',
'Content-Type': 'application/x-www-form-urlencoded'
},
data: data
};
See if the API likes the new encoding?

Unable to call Gitlab API with fetch in javascript

I have below API for fetching all jobs on a project in gitlab:
fetch("https://git.nmlv.nml.com/api/v4/projects/project_id_here/jobs", {
method: 'GET',
headers: {
'Authorization': 'Basic my-token-here'
},
'Accept': 'application/json',
'mode': "no-cors"
})
.then(response => {
console.log("hello")
return response.text();
})
.then(
text => {
var result= JSON.parse(text);
console.log(text)
}).catch(err=>{
console.log(err);
})
The above request works fine in Postman with the same token but here it is saying that the request is unauthorized. The problem is on the Gitlab API docs, they haven't specified how the request in javascript should look like. for your reference, here is the API that I want to call. I know something is incorrect in the way I have framed the API's header. Can anyone help me to find how to frame the request correctly.
Thanks
EDIT
The problem now is that when I run same request on browser inside an html page, response is coming fine. But it is not working inside a node script. The control is not going to then or catch block.

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).

Make an api write a post request to a file

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

angular $resource delete won't send body to express.js server

hye,
i am building an app with angular.js and node.js (Express.js) on the server side.
for some reason i am having a problem handling a delete request. no body is getting to the server side.
this is my angular.js resource code:
$scope.deleteProject = function(projectName){
var postData = {username: 'name', projectName: projectName};
Project.deleteProject.delete({}, postData,
function(res){
alert('Project Deleted');
},
function(err){
alert(err.data);
});
}
on the server side i have this:
var deleteProject = function(req, res){
console.log(req.body);
console.log(req.params);
if (req.body.projectName){
//do something
return res.send(200);
}
else
return res.send(400, 'no project name was specified');
}
now for some reason there is no body at all!! it is empty.
i have defined the route as app.delete.
if i change the route in node.js to post and in angular.js to save it works fine.
what am i missing here (banging my head).
thanks.
As per this stack overflow question and the $http service source code, a DELETE request using $http does not allow for data to be sent in the body of the request. The spec for a DELETE request is somewhat vague on whether or not a request body should be allowed, but Angular does not support it.
The only methods that allow for request bodies are POST, PUT, and PATCH. So the problem is not anywhere in your code, its in Angular's $http service.
My suggestion would be to use the generic $http(...) function and pass in the proper method:
$http({
method: 'DELETE',
url: '/some/url',
data: {...},
headers: {'Content-Type': 'application/json;charset=utf-8'}
})
Angular by default sends the Content-Type as text/plain for DELETE requests. Just add this to the headers:
var config = {
method: "DELETE"
url: yourUrl
data: yourData
headers: {"Content-Type": "application/json;charset=utf-8"}
};
$http(config);
If you want to add them to every single DELETE request add this to the app.config method in your main controller:
$httpProvider.defaults.headers.delete = { "Content-Type": "application/json;charset=utf-8" };
If you want to use the $resource object instead of $http you need to add hasBody and headers as follow:
delete: {
method: 'DELETE',
hasBody: true,
headers: {"Content-Type": "application/json;charset=UTF-8"}
}
Worked for me
Just ran into this problem. You'll have to use url params to send an id with delete.
in express:
app.delete('/api/user/:userId', user.remove);
and add to the url in angular:
$http({url: 'whatever/api/'+obj.id, method: 'DELETE'}) ...
The following works for me:
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
$httpProvider.defaults.headers.common['Content-Type'] = 'application/json;charset=utf-8';
XMLHttpRequest is optional but useful if you are sending ajax.
https://docs.angularjs.org/api/ng/provider/$httpProvider for more information.
This worked for me.
$httpProvider.defaults.headers.delete = { "Content-Type": "application/json;charset=utf-8" };
And then
$http.delete(url, { data: data })

Resources