Nodejs sending external API POST request - angularjs

i am trying to send a POST request from my angularjs controller to the nodejs server which should then send a full POST request to the external API and this way avoid CORS request as well as make it more secure as i'm sending relatively private data in this POST request.
My angularjs controller function for making the post request to the nodejs server looks like this and it works fine:
var noteData = {
"id":accountNumber,
"notes":[
{
"lId":707414,
"oId":1369944,
"nId":4154191,
"price":23.84
}
]
}
var req = {
method: 'POST',
url: '/note',
data: noteData
}
$http(req).then(function(data){
console.log(data);
});
Now the problem lies in my nodejs server where i just can't seem to figure out how to properly send a POST request with custom headers and pass a JSON data variable..
i've trierd using the nodejs https function since the url i need to access is an https one and not http ,i've also tried the request function with no luck.
I know that the url and data i'm sending is correct since when i plug them into Postman it returns what i expect it to return.
Here are my different attempts on nodejs server:
The data from angularjs request is parsed and retrieved correctly using body-parser
Attempt Using Request:
app.post('/buyNote', function (req, res) {
var options = {
url: 'https://api.lendingclub.com/api/investor/v1/accounts/' + accountNumber + '/trades/buy/',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': apiKey
},
data = JSON.stringify(req.body);
};
request(options, function (error, response, body) {
if (!error) {
// Print out the response body
// console.log(body)
console.log(response.statusCode);
res.sendStatus(200);
} else {
console.log(error);
}
})
This returns status code 500 for some reason, it's sending the data wrongly and hence why the server error...
Using https
var options = {
url: 'https://api.lendingclub.com/api/investor/v1/accounts/' + accountNumber + '/trades/buy/',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': apiKey
}
};
var data = JSON.stringify(req.body);
var req = https.request(options, (res) => {
console.log(`STATUS: ${res.statusCode}`);
console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
res.setEncoding('utf8');
res.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
res.on('end', () => {
console.log('No more data in response.');
});
});
req.on('error', (e) => {
console.log(`problem with request: ${e.message}`);
});
req.write(data);
req.end();
Https attempt return a 301 status for some reasons...
Using the same data, headers and the url in Postman returns a successful response 200 with the data i need...
I don't understand how i can make a simple http request...
Please note: this is my first project working with nodejs and angular, i would know how to implement something like this in php or java easily, but this is boggling me..

So after a lot of messing around and trying different things i have finally found the solution that performs well and does exactly what i need without over complicating things:
Using the module called request-promise is what did the trick. Here's the code that i used for it:
const request = require('request-promise');
const options = {
method: 'POST',
uri: 'https://requestedAPIsource.com/api',
body: req.body,
json: true,
headers: {
'Content-Type': 'application/json',
'Authorization': 'bwejjr33333333333'
}
}
request(options).then(function (response){
res.status(200).json(response);
})
.catch(function (err) {
console.log(err);
})

Related

Getting bad request from server (Spring boot) when using axios request

I'm currently stuck sending a request to my server and can not get a response. I have tried it on postman and it runs completely fine. However, when I try to put it on react, the back-end always response with a bad request.
Here is my code for the back-end
#GetMapping(value = "/searchPatient")
public ResponseEntity<?> searchPatients(#RequestParam String id_num,
#RequestParam String name) {
List<PatientForSearchDto> patientForSearchDtos = patientService.viewSearchedPatient(id_num, name);
return ResponseEntity.status(HttpStatus.OK).body(
new ResponseObject("ok", "Success", patientForSearchDtos)
);
}
Here is my code for Front end (react)
async function sendRequest () {
const formData = new FormData();
formData.append('id_num', id_num);
formData.append('name', name);
console.log(formData)
console.log(formData.get('name'))
console.log(formData.get('id_num'))
const config = {
method: 'get',
url: 'http://localhost:8080/api/searchPatient',
// headers : {
// 'Content-Type': 'from-data'
// },
data : formData
};
await axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
setPatientList(response.data.data.object)
})
.catch(function (error) {
console.log(error);
});
}
Here is what I get when sending request via postman
enter image description here
Here is when sending request using react
enter image description here
From the Axios docs about Request Config data param:
// data is the data to be sent as the request body
// Only applicable for request methods 'PUT', 'POST', 'DELETE , and
'PATCH'
So, data with GET method is not supported.
Can't you use params instead?

can i send form-data with axios with delete request in react?

i need send this request with axios.
i need header as multipart request, like below
headers: {
"Content-type": "multipart/form-data",
},
I used spring boot for backend. It expect maltipart not application/json. I tried below code, But it not worked for multipart.
axios.delete(URL, {
headers: {
Authorization: authorizationToken
},
data: {
source: source
}
});
Thanks a lot #Sinan Yaman. I generated it using POSTMAN. Answer is
var axios = require('axios');
var FormData = require('form-data');
var data = new FormData();
data.append('keyName', 'project/photoes/1613388881570-note1.txt');
var config = {
method: 'delete',
url: 'localhost:8080/storage/deleteFile',
headers: {
...data.getHeaders()
},
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
Typically before make frontend we test our backend with postman. For any type of frontend http calls code can automatically generate using postman. This is awesome feature of POSTMAN. Follow below steps.
Press the code button
Select the your backend code environment

CORS error while sending request from Browser to play server even after sending CORS header

I have a REST API developed using Play Framework/Java and front end developed in Angular JS.
I am trying to call a POST method fron the Angular Client to the server using the following code:
$scope.login = function () {
console.log('login called');
var loginURL = 'http://localhost:9000/login';
var loginInfo = {
'email': $scope.email,
'password': $scope.password
};
$http({
url: loginURL,
method: 'POST',
data: loginInfo,
headers: { 'Content-Type': 'application/json' }
}).then(function (response) {
console.log('SUCCESS: ' + JSON.stringify(response));
$scope.greeting = response.status;
}, function (response) {
console.log('ERROR: ' + JSON.stringify(response));
});
}
This is the code at my server:
public Result doLogin() {
ObjectNode result = Json.newObject();
result.put("status", "success");
return ok(result).withHeader("Access-Control-Allow-Origin", "*");
}
And this is the application conf file:
#allow all hosts.
play.filter.hosts {
allowed = ["."]
}
#allow CORS requests.
play.filters.cors {
allowedOrigins = ["*"]
}
Yet even after enabling CORS, I am getting error in console in both Firefox and Google Chrome:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:9000/login. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
ERROR: {"data":null,"status":-1,"config":{"method":"POST","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"http://localhost:9000/login","data":{"email":"xxx","password":"xxx"},"headers":{"Content-Type":"application/json","Accept":"application/json, text/plain, /"}},"statusText":""}
I do know that the server is sending the correct response and the correct header because when I do the POST from Postman, I can see the response and also the headers containing {"Access-Control-Allow-Origin", "*"} in Postman.
So then, what could be the problem? Is there something I am missing from the Client side?
The difference between POSTMAN request and browser request is browser sends an OPTIONS request before the actual POST / GET request.
To be able to accept OPTION request with your play framework allowedHttpMethods = ["GET", "POST" ,"OPTIONS"]
for follow this link
Play Framework 2.3 - CORS Headers
This causes a problem accessing CORS request from a framework (like angularjs). It becomes difficult or the framework to find what was the options request for and take action properly.
For fixing your problem you will need to analyze how the options request going and how it's being interpreted and how to overcome. But in general, I suggest using "fetch" built-in request for this, which supports the promises so can be chained easily with angularjs code
so your code will look something like this
$scope.login = function () {
console.log('login called');
var loginURL = 'http://localhost:9000/login';
var loginInfo = {
'email': $scope.email,
'password': $scope.password
};
fetch(loginURL, {
method: 'post',
headers: {
"Content-type": "application/json"
},
body: loginInfo
}).then(function (response) {
console.log('SUCCESS: ' + JSON.stringify(response));
$scope.greeting = response.status;
}, function (response) {
console.log('ERROR: ' + JSON.stringify(response));
});
}

React + fetch request

I am reading this article fetch API and trying to understand how to work with fetch in React. Firstly, could you explain what is request headers ?
Than,
in angular we do something like:
$http.get('/someword').success(function(response) {
console.log('i got the data i requested');
var variable = response;
}
and than on server side in express I can write:
var app = express();
app.get('/thissomeword', function(req, res) {
console.log('I got a GET request')
res.json(someVariableWithData)
})
How to do the same with fetch ? And the main question where and when I need to do it ? I understand that i need after i get data to do this.setState({}) for using my data later, but HOW is for me huge conundrum.
Here you have great facebook documentation:
https://facebook.github.io/react-native/docs/network.html
with example that shows what you want
headers in request
Sometimes you need header in request to provide access token or content-type (especially in POST request)
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
})
})
Promises instead of callbacks
In your example you pass callbacks (req and res) to your request, in fetch you have Promises so you get response as a paramether of then or error message in catch.
fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
return responseJson.movies;
})
.catch((error) => {
console.error(error);
});
Request Headers
As basic, Request Headers are set by the browsers and the application developers, this is use to tell the web server what the client is sending and what can it accept back in return.
Reference
Fetch
Fetch is used to make async network calls. It has a simpler API support based on promises. I'll make your code cleaner with less number of lines.
Reference

AngularJS HTTP GET request returning cached data

In my AngularJS app I am sending HTTP GET request as below.
MyService.HttpReq("testUrl", "GET", null);
HttpReq Method is defined in a service and implemented as below:
this.HttpReq = function(URL, method, payload)
{
$http({
url: URL,
method: method,
cache: false,
data: postData,
headers: {
'Content-Type': 'application/json',
}
}).success(function(response)
{
console.log("Success: "+JSON.stringify(response));
}).error(function(data, status)
{
console.error("Error");
});
}
First of all is this the right way of sending HTTP request in AngularJS?
The problem that I am facing is, some times I get cached data as response and HTTP request is not hitting the server. what can be the issue?
UPDATE
As per the comment and answer I have updated my HTTP request code as below, but still getting same issue.
this.HttpReq = function(URL, method, payload)
{
$http({
url: URL,
method: method,
cache: false,
data: payload,
headers: {
'Content-Type': 'application/json',
'Cache-Control' : 'no-cache'
}
}).
then(
function(response)
{
var data = response.data;
console.log("Success: "+JSON.stringify(data));
},
function(response)
{
var data = response.data || "Request failed";
var status = response.status;
console.error("Error: "+JSON.stringify(data));
}
);
}
IE Browsers will catch ajax get requests even if we add cache control headers to the response. Only way i found to solve the issue is to add some random parameter to the request. Please make sure the api have no problem even if you send extra parameters
MyService.HttpReq("testUrl?ts=" + Date.now(), "GET", null);
Just add cache: false attribute to config object.
https://docs.angularjs.org/api/ng/service/$http#caching
Also you can add header: 'Cache-Control' : 'no-cache'

Resources