My endpoint will send a response like this:
res.status(400).json({"note","this email is already taken"});
With React I am using axios as follows
export const signUpUser = (email, password) => {
const headers = {
"Content-Type": "text/plain",
};
return axios
.post(
https://domain.something + "/signup",
{ email, password },
{ headers ,}
)
.then((res) => {
return res;
})
.catch((err) => {
return err;
});
};
postman can parse it as follows:
however I can not extract the JSON with react this is what displays console log shows:
By default 400 is the code for bad request, have a try to change the code to 200 or 2xx.
After some reading I learned that Axios processes express responses differently than other libraries. It treats the response as an object and only appears to take the first one (chaining did not work).
solution:
return res.json({
message: "This email is currently in use.",
status: 400,
foo: "bar",
data: "this is the data",
})
result:
Related
Hi I am beginner in sveltekit. I try to get post data in sveltekit here is my POST Request.
I am using axios to send post data.
const request = await axios
.post("/api/user", {
username,
email,
password,
repassword
})
.then((e) => {
console.log(e)
})
.catch((e) => {
console.error(e);
});
and this is my POST Endpoint:
// src/routes/user/+server.ts
export const POST = async({request}) => {
console.log(request)
return new Response(JSON.stringify({something: 1}))
}
this api working fine with GET methods.
Looks like the routes just don't match.
src/routes/user/+server.ts equates to just /user.
I have set up payments with stripe using Netlify function by following this article https://www.netlify.com/blog/2020/04/22/automate-order-fulfillment-w/stripe-webhooks-netlify-functions/ and in my Stripe dashboard I get error saying that:
Webhook Error: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? https://github.com/stripe/stripe-node#webhook-signing
Now I am not sure if the user gets confirmation email, Sendgrid does not show any activity, however it has not shown any when I was testing this flow previously, and although I received confirmation email. Unfortunately back then I pressed resend by my webhook activity details in Stripe dashboard, and I am not sure if I should be resending those or do they go through. Would anyone be able to tell me what is wrong with my code?
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
const sgMail = require("#sendgrid/mail");
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
exports.handler = async ({ body, headers }) => {
try {
const stripeEvent = stripe.webhooks.constructEvent(
body,
headers["stripe-signature"],
process.env.STRIPE_WEBHOOK_SECRET
);
if (stripeEvent.type === "charge.succeeded") {
const emailTo = stripeEvent.data.object.billing_details.email;
const msg = {
to: emailTo,
from: process.env.FROM_EMAIL_ADDRESS,
subject: `Thanks!`,
html: `elox`,
};
await sgMail.send(msg);
}
return {
statusCode: 200,
body: JSON.stringify({ received: true }),
};
} catch (err) {
console.log(`Stripe webhook failed with ${err}`);
return {
statusCode: 400,
body: `Webhook Error: ${err.message}`,
};
}
};
Thanks!
I got the same issue.
Locally with the stripes-cli everything works fine.
It seems that the lambda didn't hand over the raw body to the stripes.webhook.constructEvent.
Therefore my solution was to change the method signature to the following and use the event.body object.
exports.handler = async(event, context ) => {
try {
const stripeEvent = stripe.webhooks.constructEvent(
event.body,
event.headers['stripe-signature'],
endpointSecret
);....
I am making a Discord bot, and I want it to be able to use the YouTube API to fetch new uploads from a specific channel.
I have searched elsewhere, but they all say how to upload videos, not how to track uploads.
Is this possible, and how can I do it?
Edit: Tried PubSubHubbub but it was very confusing and I couldn't get it to work
Here an example built on top of Node.js (v12) and Fastify and published with ngrok:
I wrote some comments explaining what it is happening:
const fastify = require('fastify')({ logger: true })
const xmlParser = require('fast-xml-parser')
const { URLSearchParams } = require('url')
const fetch = require('node-fetch')
// add an xml parser
fastify.addContentTypeParser('application/atom+xml', { parseAs: 'string' }, function (req, xmlString, done) {
try {
const body = xmlParser.parse(xmlString, {
attributeNamePrefix: '',
ignoreAttributes: false
})
done(null, body)
} catch (error) {
done(error)
}
})
// this endpoint needs for authentication
fastify.get('/', (request, reply) => {
reply.send(request.query['hub.challenge'])
})
// this endpoint will get the updates
fastify.post('/', (request, reply) => {
console.log(JSON.stringify(request.body, null, 2))
reply.code(204)
reply.send('ok')
})
fastify.listen(8080)
.then(() => {
// after the server has started, subscribe to the hub
// Parameter list: https://pubsubhubbub.github.io/PubSubHubbub/pubsubhubbub-core-0.4.html#rfc.section.5.1
const params = new URLSearchParams()
params.append('hub.callback', 'https://1f3dd0c63e78.ngrok.io') // you must have a public endpoint. get it with "ngrok http 8080"
params.append('hub.mode', 'subscribe')
params.append('hub.topic', 'https://www.youtube.com/xml/feeds/videos.xml?channel_id=UCfWbGF64qBSVM2Wq9fwrfrg')
params.append('hub.lease_seconds', '')
params.append('hub.secret', '')
params.append('hub.verify', 'sync')
params.append('hub.verify_token', '')
return fetch('https://pubsubhubbub.appspot.com/subscribe', {
headers: { 'content-type': 'application/x-www-form-urlencoded' },
body: params,
method: 'POST'
})
})
.then((res) => {
console.log(`The status must be 204. Received ${res.status}`)
// shows the error if something went wrong
if (res.status !== 204) {
return res.text().then(txt => console.log(txt))
}
})
I used my channel id to do some testing, consider that the notification is not in real-time, the POSTs are triggered after several minutes usually.
I'm trying to make a POST request using axios to my firebase cloud-function on form submit in react app. But I get '500' error everytime I make a request with an html-page response This app works best with javascriot enabled.
Latest Update:
It looks like there is no issue with cloud function
code. Rather more of a react-component issue. I used Postman to send
the POST request with header prop Content-Type set to application/json
and sending body in raw format {"email": "example_email"} and got
expected response from the cloud function. But when sent the request from
react component above, I get an html file response saying the app
works best with javascript enabled
I've tried setting Content-Type to both Application/json and multipart/form-data as I suspected it to be an issue but still got no luck.
Following is my code for cloud function and react submit form:
Cloud Function
const functions = require('firebase-functions');
const cors = require('cors')({ origin: true })
const runThisFunc1 = require(./libs/runThisFunc1);
const runThisFunc2 = require(./libs/runThisFunc2);
exports.wizardFunc = functions.https.onRequest((request, response) => {
cors(request, response, () => {
let email = request.body.email;
try {
return runThisFunc1(email)
.then(data => {
console.log("Word Done by 1!");
return runThisFunc2(data);
})
.then(res => {
console.log("Word Done by 2!");
return response.status(200).send("Success");
})
.catch(err => {
console.error("Error: ", err.code);
return response.status(500).end();
});
}catch(err) {
return response.status(400).end();
}
});
});
React-Form-Component Snippet
import axios from 'axios'
...
handleSubmit = e => {
e.preventDefault()
const { email } = this.state
axios({
method: 'post',
url: `${process.env.REACT_APP_CLOUD_FUNCTION_ENDPOINT}`,
data: { email: email },
config: {
headers: {
'Content-Type': 'multipart/form-data'
}
}
})
.then(res => {
//do something with reponse here
})
.catch(error => {
console.error(error)
})
}
...
Is there something wrong I am doing in the code or the request config is wrong?
I'm trying to send a CORS POST request to my API and it throws a TypeError every time I use the 'Authorization' header. The request doesn't even get sent, so the server is not involved. But this only happens in my tests. When I try it in Chrome it works just fine.
Here is the function that I'm testing:
export const postNewEmployee = formData => {
return fetch('http://localhost:3003', {
method: 'POST',
headers: {
'Authorization': 'Bearer test123',
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
})
.then(response => response)
.catch(error => {
throw error;
});
};
And its test:
import * as API from './api';
describe('postNewEmployee', () => {
it('posts the form data asynchronously', () => {
let formData = {
employee: {
name: 'Test Person',
email: 'test#person.nu',
address: 'an adress 123'
}
};
return API.postNewEmployee(formData)
.then(json => {
expect(json.status).toEqual(201);
}).catch(error => {
console.log(error);
});
});
});
The application is a react/redux app created with create-react-app, so I'm using Jest and JSDOM to test this. The thing is, if I comment out the Authorization header from the fetch()-call, it works fine. But if I add that header I get this:
TypeError: Cannot convert undefined or null to object
at Object.getRequestHeader (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:20:23)
at setDispatchProgressEvents (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:909:38)
at XMLHttpRequest.send (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:700:11)
at /Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/whatwg-fetch/fetch.js:429:11
at Object.<anonymous>.self.fetch (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/whatwg-fetch/fetch.js:373:12)
at Object.<anonymous>.exports.postNewEmployee.formData [as postNewEmployee] (/Users/johanh/Kod/react-app/src/api/api.js:20:10)
at Object.it (/Users/johanh/Kod/react-app/src/api/api.test.js:75:16)
at Object.<anonymous> (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jest-jasmine2/build/jasmine-async.js:42:32)
at attemptAsync (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jest-jasmine2/vendor/jasmine-2.4.1.js:1919:24)
at QueueRunner.run (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jest-jasmine2/vendor/jasmine-2.4.1.js:1874:9)
And as I said, this only happens in the test. In the browser it works fine.
I feel like I'm missing something obvious here, but I just can't see it. I've looked in the fetch spec and the jsdom documentation, but to no avail. Any ideas?
Normally you should not make real requests in a unit test. The best way to handle this is to use a mock instead of the real fetch implementation.
I assume you are using the JS implementation of fetch. So you can set fetch to what ever you want in your test.
import * as API from './api';
describe('postNewEmployee', () => {
it('posts the form data asynchronously', () => {
// set fetch to a mock that always returns a solved promise
const fetch = jest.fn((url, options) => return Promise.resolve({status: 201}))
global.fetch = fetch;
let formData = {
employee: {
name: 'Test Person',
email: 'test#person.nu',
address: 'an adress 123'
}
};
//test that fetch was called with the correct parameters
expect(fetch.mock.calls[0][0]).toBe('http://localhost:3003')
expect(fetch.mock.calls[0][1]).toEqual(formData)
return API.postNewEmployee(formData)
.then(json => {
expect(json.status).toEqual(201);
}).catch(error => {
console.log(error);
});
});
});