201 status node express API always failing - javascript

I am trying to make an api through express. However, the response from the server i am getting is 201 created. The HTTP request i am trying to make through promises is interpreting the then process as false and it continually goes through a failed criteria.
Any idea on how i can get 201 created through the example below.
Example: The output even while being successful automatically goes through error status.
router.get('/example', session, function (req, res) {
example(req.body, req.session.token).then(
(response) => {
res.json(response);
},
(err) => {
if (err.status) {
res.status(err.status).json({
status: err.status,
message: err.message
});
} else {
res.status(constants.HTTP_INTERNAL_SERVER_ERROR).json({
status: constants.HTTP_INTERNAL_SERVER_ERROR,
message: 'Internal Server Error'
});
}
}
);
});
module.exports.example = (body, token) => {
return new Promise((resolve, reject) => {
const mainToken = createRawToken(token);
request.post(
{
url: `${endpoint}`,
body: JSON.stringify(body),
headers: {
Authorization: mainToken,
"Content-Type": "application/json"
}
},
(error, response, bdy) => {
resolve(requestService.handleResponse(error, response, bdy, constants.HTTP_OK));
}
);
});
};

I think your problem is in the example function. The promise seems fine but i am assuming that you're naming your constants well.
constants.HTTP_OK should be constants.HTTP_CREATED. Behind them i am assuming that HTTP_OK is 200 and HTTP_CREATED should be 201.

Related

How to convert a CURL request into an axios request?

I just successfully curled here:
curl -X POST https://jenkins-url/job/MyJob/job/some-job/job/master/build --user myemail:mypassword -H 'Jenkins-Crumb: mycrumb'
now I want to use axios inside my lambda
so I have this:
const axios = require('axios')
exports.handler = async (event) => {
const url = "my-url";
try {
const res = await axios.post(url, {}, {
auth: {
username: 'user',
password: 'passowrd'
},
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Jenkins-Crumb": "my-crumb"
},
}).then(function(response) {
console.log('Authenticated');
}).catch(function(error) {
console.log('Error on Authentication');
});
console.log(res)
return {
statusCode: 200,
body: JSON.stringify(res)
}
} catch (e) {
console.log(e)
return {
statusCode: 400,
body: JSON.stringify(e)
}
}
};
but when I trigger the lambda it returns with: failed with the error "Request completed but is not OK"
not sure if I'm doing something wrong somewhere but seems to be everything is correctly mapped from CURL to axios
You have a few issues:
In your .then(...) handler, you are doing a console log, but you aren't returning anything from that function. Therefore, res is going to be undefined.
You're doing a JSON.stringify on res. res would be an axios response, not the response body. Stringifying the axios response is a bad idea, because it contains hefty object references and also circular references. You want res.data to give you the response data.
The error returned from Axios may also contain these heavy objects and circular references. In my experience, you can actually crash node when trying to serialize responses and errors from axios.
Here's how I'd modify your function:
const axios = require('axios')
exports.handler = async (event) => {
const url = "my-url";
try {
const res = await axios.post(url, {}, {
auth: {
username: 'user',
password: 'passowrd'
},
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Jenkins-Crumb": "my-crumb"
},
});
return {
statusCode: 200,
body: JSON.stringify(res.data)
}
} catch (e) {
console.log(e)
return {
statusCode: 400,
// Don't do JSON.stringify(e).
// e.response.data will be the axios response body,
// but e.response may be undefined if the error isn't an HTTP error
body: e.stack
}
}
};

A specific URL causes axios nuxt module to not run callback

So I have setup two buttons called "Confirm" and "Delete" on my nuxt.js page. Each button, when clicked, will run confirm() and delete() respectively. The code for the two functions are nearly identical, the only difference being that the URLs are different. When running delete(), it performs a GET request with axios and the callback is run perfectly and does what I want it to do. However, when running confirm(), it performs the request but the callback isn't run.
I thought maybe the API server isn't responding. However, when I checked the logs, the response is actually being sent.
1zcu ——> GET /api/pending/delete/5d554a5d9ddb8079158eefcc
1zcu <—— 200 OK 15 B application/json; charset=utf-8 (<—> 326.1 ms)
yefy ——> GET /api/pending/confirm/5d554a5c9ddb8079158eefcb
yefy <—— 200 OK 14 B application/json; charset=utf-8 (<—> 540.9 ms)
So I tried changing the URL in the confirm() function to match the one in the delete() function and sure enough, it started working.
Functions
confirm(id) {
this.setConfirming(id);
const url = CON_URL + id;
this.$axios.$get(url).then((res) => {
if (!res.error) {
console.log(res)
this.refresh();
}
});
},
discard(id) {
this.setDeleting(id);
const url = DEL_URL + id;
this.$axios.$get(url).then((res) => {
if (!res.error) {
console.log(res)
this.refresh();
}
});
},
URLs
const DEL_URL = "/api/pending/delete/";
const CON_URL = "/api/pending/confirm/";
Buttons
<td v-if="!enquiry.isConfirming"><button v-on:click="confirm(enquiry._id)" class="button is-primary">Confirm</button></td>
<td v-if="!enquiry.isDeleting"><button v-on:click="discard(enquiry._id)" class="button is-danger">Discard</button></td>
Express endpoints
router.get('/delete/:id', (req, res) => {
Pending.findOneAndDelete({ _id: req.params.id }, (err, pending) => {
if (err) {
res.json({ error: true });
} else {
res.json({ error: false });
}
});
});
router.get('/confirm/:id', (req, res) => {
Pending.findOneAndDelete({ _id: req.params.id }, (err, pending) => {
if (err) {
res.json({ error: true });
} else {
const confirmed = new Booking(pending);
confirmed.save((err, result) => {
if (err) {
res.json({ error: true });
} else {
res.json({ error: false });
}
});
}
});
});
Promise.then is only executed if the task completed without exception. You may also need to attach a callback for the error condition with Promise.catch:
this.$axios.$get(url)
.then((res) => {
console.info(res);
})
.catch((err) => {
console.error(err);
})
.finally(() => {
console.info('done');
});

Send back data from node.js to client side javascript

what I´m trying to do is the following I already set a fetch connection from client side JS to the server Node.JS when a person click on a button in HTML which triggers that in the server side looks for an element in the MongoDB database in it find´s it, but my question is how do I send that found element back to the client side JS.
Javascript Code:
var button = document.getElementById("1");
button.addEventListener("click", idss);
function idss() {
var id = this.id;
var data = {
name : id
}
fetch("/clicked", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(function(response) {
if(response.ok) {
console.log('awesome');
return;
}
throw new Error('Request failed.');
})
.catch(function(error) {
console.log(error);
});
}
NODE JS:
app.post("/clicked", (req, res) => {
var pro = (req.body.name);
Number(pro);
Product.findOne({"id": pro}, function(err, foundLList) {
if(err) {
console.log(err);
} else {
console.log(foundLList); //THE ELEMENT IS FOUND
}
}
);
});
What I´m trying to do is to send the found element to Javascript so I can added to another variable.
You have to use res object to send data back to client. Your node code will be:
app.post("/clicked", (req, res) => {
var pro = (req.body.name);
Number(pro);
Product.findOne({
"id": pro
}, function(err, foundLList) {
if (err) {
console.log(err);
return res.status(500).json({
ok: false,
error: err
});
} else {
console.log(foundLList); //THE ELEMENT IS FOUND
return res.status(200).json({
ok: true,
data: foundLList
});
}
});
});
and on client side, you can read the data like this:
fetch("/clicked", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(function(response) {
if (response.ok) {
console.log('got data: ', response.data);
}
throw new Error('Request failed.');
})
.catch(function(error) {
console.log(error);
});
}

Why is request-promise not returning the results to postman and angular 2's map?

We have an Angular 4 service with a function like this:
callPostAPI() {
var headers = new Headers();
headers.append('Content-Type', 'application/json');
let options = {}; //passing no options
return this.http.post('http://localhost:9000/v1/api/testapi', options, {
headers: headers
})
.map((response: Response) => {
return response.json();
})
.catch((error: Response) => {
return Observable.throw(error || 'server error');
});
}
The rp function is like this:
app.post("/v1/api/testapi", (req, res) => {
rp({
method: 'GET',
url: 'http://maps.googleapis.com/maps/api/geocode/json',
qs: {
address: '66309'
}
})
.then(res => {
console.log(res); //proper results received
return res;
}).catch(err => {
return err;
});
}
However, this is not returning any response when called either from postman or through Angular 4 service function.
The results are received and we can see them on the console as well. All this is working without headers.
Why is request-promise not returning the results?
You never handle the result of request promise on your server side. I'm assuming you are using express, try this:
app.post("/v1/api/testapi", (req, res, next) => {
rp({
method: 'GET',
url: 'http://maps.googleapis.com/maps/api/geocode/json',
qs: {
address: '66309'
}
})
.then(result => {
console.log(res); //proper results received
return res.status(200).json(result);
}).catch(next);
}
Use subscribe insted of then , i too had same issue but trying the above solved for me.

Asynchronous Javascript Request Issue (Node, request-promise module)

I am building an application and having an issue with making a request from the client, sending it to my server, having the server make the API call and then send the result back to the client. I am using Node and the Request-Promise module.
Here is the client side code:
$(document).ready(function() {
var artistSearch = () => {
const q = $('.artistName').val();
$.ajax({
type: "POST",
url: "http://localhost:3000/request",
data: {artist: q},
})
.done(function(data) {
console.log('data: ', data)
})
};
$(".artistSearch").submit( () => {
artistSearch();
});
});
This successfully makes a request to the server:
app.post('/request', (req, res) => {
const artist = req.body.artist;
const searchURL = "https://api.spotify.com/v1/search? q="+artist+"&type=artist";
var targetObj;
var options = {
uri: searchURL
};
rp(options)
.then(function (data) {
console.log(data);
res.send(data);
})
.then(function() {
console.log('complete');
})
.catch(function (err) {
console.log('error')
});
});
Which ultimately successfully grabs the data from the API call, but never sends it back to the client! If I do res.send() outside of my .then promise, I can receive data on the client end.
Is there something I am missing? Thanks in advance!
Try this
var options = {
uri: searchURL,
simple: false,
};
rp(options)
.then(function (data) {
console.log(data);
res.status(200).send(data).end();
})
.then(function() {
console.log('complete');
})
.catch(function (err) {
console.log('error')
});
I think the client did receive data, but the connection didn't terminate correctly as it thinks there are more data. This is because you didn't specify the header and the module http couldn't figure out the content-length.
rp(options)
.then(function (data) {
console.log(data);
// res.send(data);
// assume data is JSON.
res.setHeader (200, {'Content-Type': 'application/json',
'Content-Length':data.byteLength});
res.end(data); //Send data immediately.
})
...
If data is a string, you will need to use data.length instead. In fact, if data is a string, then by default the header is {'Content-Type': 'application/json', 'Content-Length':data.length}

Categories

Resources