Okay, so I feel like this is way more trivial than it needs to be, but for some reason, I cannot get information out of my "body" when it is passed to the get method. I've tried a number of different ways to access it, but nothing sees to do the trick. Guidance is much appreciate. Below is my code:
---------------fetch method----------------
var x = e.target.phone.value;
var y = e.target.email.value;
console.log(x); // proper output
console.log(y); // proper output
fetch('/api/insert',
{
accept: 'application/json',
body: {
phone2: x,
email2: y
}
});
------------get method--------------
app.get('/api/insert', (req, res) => {
const phone = req.body.phone2; <-- Am I accessing the data incorrectly?
const email = req.body.email2; <-- Am I accessing the data incorrectly?
console.log(phone); // getting undefined here... Why?
console.log(email); // and here...
});
});
You need to use req.query.phone2 and req.query.email2.
Parameters for a GET request are sent as query parameters on the URL (no body is sent with a GET request) and Express puts query parameters in req.query.
I think you should call it like this:
fetch('......')
.then((response) => response.json())
.then((responseJson) => {
return responseJson.movies;
})
.catch((error) => {
console.error(error);
});
Related
I'm trying to make a post request to the server,but it returns 400 error.
:
this is react function
const handleSubmit = () => {
const bookInstanceObject = {
imprint: imprint,
};
axios
.post('http://localhost:3001/catalog/bookinstance/create', bookInstanceObject)
.then(res => {
console.log(res.data);
})
.catch(error => {
console.log(error);
});
};
and this is the server side:
router.post('/bookinstance/create', (request, response, next) => {
const body = request.body;
const bookInstance = new BookInstance({
imprint: body.title,
});
bookInstance
.save()
.then(savedBook => {
response.json(savedBook.toJSON());
})
.catch(error => next(error));
});
any idea ?
What I think is happening
The front end's handleSubmit function is POSTing to /catalog/bookinstance/create, while the server is expecting it to come to /bookinstance/create.
Simple typo, easy to miss when your stressing over it not working.
How to fix?
Change the URLs to match.
Either:
change the front-end's POST url to /bookinstance/create,
or:
change the server's expected route to router.post('/catalog/bookinstance/create',
Why is it a GET in the error log?
I don't know but I suspect that this error is about a GET request somewhere else in your code.
Please let us know in the comments if the error goes away with this fix. (Assuming my fix works)
I need help to integrate a few actions inside a function.
I get a call from PayPal, then i need to :
Access my DB to compare.
If ok send 200 OK
Send the request body back.
Currently - I do (3) only, and it somehow works without (2).
exports.contentServer = functions.https.onRequest((request, response) => {
....
....
if(request.path === paid)
{
if (request.method !== "POST")
response.status(405).send("Method Not Allowed");
else {
let ipnTransactionMessage = request.body;
let formUrlEncodedBody = querystring.stringify(ipnTransactionMessage);
let verificationBody = `cmd=_notify-validate&${formUrlEncodedBody}`;
//______________
//** at this point i need to read a firebase collection and return 200OK , ONLY THEN DO THE POST BELOW
var docRef = admin.firestore().collection('All').doc(ipnTransactionMessage.custom);
docRef.once('value').then(function(snapshot) {
console("our data to compare",snapshot);
res.status(200); // ?
});
//**** how do i do the next only after the previous ?
let options = {
method: 'POST',
uri: "https://ipnpb.sandbox.paypal.com/cgi-bin/webscr",
body: verificationBody
};
return rp(options)
.then(body => {
if (body === "VERIFIED") {
//** we are done here - and this actually works already
})
.then(docReference => {
console.log("Request completed");
return response.send({ result: 'ok' });
})
.catch(error => {
console.log(error);
return response.status(500).send(error);
});
See the comment in the code. After reading my DB and respond with 200 OK , only then i would like to send back the body as I do.
As Doug mentioned the code needs to go in the then clause:
I took a part of your code to shaow where the code to get executed only when firestore answers can go.
//** at this point i need to read a firebase collection and return 200OK , ONLY THEN DO THE POST BELOW
var docRef = admin.firestore().collection('All').doc(ipnTransactionMessage.custom);
docRef.once('value').then(function(snapshot) {
console("our data to compare",snapshot);
res.status(200); //
if(snapshot.exists){
// ---------------------------------
// The code that you want to get executed only
// firestore answers Goes Here
// ---------------------------------
}
});
I'm using Cypress to do some API testing, but I am struggling to access values in the JSON response body; however I can perform assertions against the body which suggests it's receiving it correctly.
Below I am trying to assign the JSON body (response.body) and then get the value of 'id' out of it:
describe('Creating a board', () => {
it('should create a board', () => {
cy.request({
method : 'POST',
url:`${requestUrl}/boards/`,
qs: {
name : "test-board",
token : token,
key : key
}
}).then((response) => {
expect(response).property('status').to.equal(200)
expect(response.body).property('id').to.not.be.oneOf([null, ""])
const body = (response.body)
boardId = body['id']
})
})
I've done numerous searches and can't find a concrete way to do it. Any help would be appreciated...
I managed to solve this by using a Promise;
Doing some further reading, I found out the then function I am executing is synchronous (I'm new to JS, pls don't hurt me).
I refactored the then function to the following:
.then((response) => {
return new Promise(resolve => {
expect(response).property('status').to.equal(200)
expect(response.body).property('id').to.not.be.oneOf([null, ""])
const respBody = response.body;
boardId = respBody['id']
resolve(boardId)
})
It's probably not entirely correct or best practice, but it will do for my demo
Although not needed anymore as you found a workaround, I've looked into my cypress code. I was able to access properties of response body followingly:
cy.request({
...
}.its('body').then((body) => {
const whatever = body.whatever;
})
I believe it basically works the same as your workaround - waiting to resolve body in a promise.
I was able to do it in the following way:
cy.request(
'POST',
url,
payload()).then((response) => {
expect(response.body).to.have.property('ReturnCode', 'Success')
expect(response.body).to.have.property('ReturnText', 'Success')
expect(response.body).to.have.property('PaymentInstructionId')
paymentID = response.body.PaymentInstructionId
})
paymentID is the variable that is filled with the value that i want from the repply.
I tested with two apis for axios put.
for one api its working fine where as with another api it throws an error.
for one api its showing request as options eventhough I gave as put and I am seeing 403 forbidden error
for this api i am facing the issue 'http:///sports/sportsId',
I debugged but still I am not able to find the issue.
is it a back-end issue
can you tell me how to fix it, providing my code snippet below
savesports = () => {
console.log("savesports---->");
console.log(this.state.sports);
let savesports = this.state.sports;
savesports.updatedBy = 'xxx';
savesports.priceRuleDescription = "test description";
let data = {
name: "yyyy",
email: "sda#gmail.com",
phone: "2321313"
};
axios
.put("https://jsonplaceholder.typicode.com/users/1", data)
.then(r => console.log("dada", r));
console.log(JSON.stringify(savesports));
axios
.put(
'http:///sports/sportsId',
savesports
// { headers: { 'Content-Type': 'application/json' } }
)
.then(r => console.log(r))
.catch(e => console.log(e));
//this.toggleDrawer("right", false);
this.setState({ right: false });
this.setState({ snackBarOpen: true });
setTimeout(() => {
this.setState({ snackBarOpen: false });
}, 6000)
};
1. Check if URL is right
I would first check if the URL is right.
Try changing http:///sports/sportsId to http://sports/sportsId if that's actually the URL you are requesting to.
2. Avoid name confusion
Both the method name and the put data variable name are the same (savesports). I would change the put data variable name to something meaningful like
let sportsData = this.state.sports;
sportsData.updatedBy = 'xxx';
sportsData.priceRuleDescription = 'test description';
3. Check authentication
403 might also be to auth error. I would check if the endpoint requires any authentication token or headers.
I'm making a chat bot where people get coins each 30 minutes, they can then spend those coins. When they spend those coins they need to be deducted, so I need to catch their command in my front-end and deduct the coins from their profile in my back-end.
This is a case of my switch case in which I catch the command that's being utilised
case `!gayOverlay`:
const requiredKluiten = 50;
fetch(`/api/users/${userstate.username}`) // fetch from Express.js server
.then(response => response.json())
.then(result => {
if (result.instakluiten >= requiredKluiten) {
client.action(channel, `${userstate[`display-name`]}, you've got enough instakluiten for this.`);
const method = `PATCH`;
const payload = {requiredKluiten};
const body = JSON.stringify(payload);
const headers = `Content-Type: application/json`;
return fetch(`/api/users/${userstate.username}`, {method, body, headers})
.then(r => console.log(`Result is `, d));
}else{
client.action(channel, `${userstate[`display-name`]}, you don't have enough instakluiten for this, you need ${requiredKluiten - result.instakluiten} more.`);
}
});
break;
I'm using PATCH to update my viewers' coins (I read Please do not patch like an idiot, but people in the comments were also against the method, so I'm not sure what the correct way is anymore now...), when I send data with postman my req.body in my back-end is filled with the data I added. However, when I execute my function (which also should have data because of my payload), my req.body is an empty object. What am I doing wrong here?
This is what's happening on the server side
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/api/users/:username', (req, res) => {
let username = req.params.username;
findUserInApi(username)
.then(foundUser => {
console.log(`foundUser is ${foundUser}`);
if (!foundUser) {
res.status(403).send('User not found in api yet');
}else{
res.json(foundUser);
}
});
});
Update
This is what's being returned in the then after my patch (changed it to PUT after the comment of Alex) https://puu.sh/shO57/362b639545.png
Update
Even when trying it like this (because of this post) it makes no difference
const data = JSON.stringify(payload);
const body = new FormData();
body.append(`json`, data);
Update
When using postman my body is always: {'requiredKluiten': 50}.
When I remove the headers (that were automatically set to application/x-www-form-urlencoded when choosing x-www-form-urlencoded to send my data) I get an empty object with Postman. When the headers are added again with x-www-form-urlencoded it works. When I select form-data however I get as req.body:
{ '------WebKitFormBoundarySAXAR2jfhUJt39US\r\nContent-Disposition: form-data; name': '"requiredKluiten"\r\n\r\n50\r\n------WebKitFormBoundarySAXAR2jfhUJt39US--\r\n' }
However, when adding the headers to my code, it still doesn't work when executing my fetch... I must still be doing something wrong :/...
This is what's being executed right now, any flaws to be spotted?
case `!gayOverlay`:
const requiredKluiten = 50;
fetch(`/api/users/${userstate.username}`) // fetch from Express.js server
.then(response => response.json())
.then(result => {
if (result.instakluiten >= requiredKluiten) {
client.action(channel, `${userstate[`display-name`]}, you've got enough instakluiten for this.`);
const method = `PUT`;
const payload = {requiredKluiten};
const body = JSON.stringify(payload);
const headers = `Content-Type: application/x-www-form-urlencoded`;
return fetch(`/api/users/${userstate.username}`, {method, body, headers})
.then(d => console.log(`Result is `, d));
}else{
client.action(channel, `${userstate[`display-name`]}, you don't have enough instakluiten for this, you need ${requiredKluiten - result.instakluiten} more.`);
}
});