I am trying to call an express endpoint with fetch from my react app and pass the body as a JSON object so that I can include more data within it. The call currently works when I set body directly to token.id, but I want to include more data. For now I'm just constructing the JSON with that one piece of data, but cannot seem to get the server to properly handle it. I have the working lines of code commented out, which I know work as I am seeing the calls make it through to the stripe API. With the new code I get as far as the token creation working, but the create customer call does not show up on the stripe API.
import React, {Component} from 'react';
import {CardElement, injectStripe} from 'react-stripe-elements';
class CheckoutForm extends Component {
constructor(props) {
super(props);
this.state = {complete: false};
this.submit = this.submit.bind(this);
}
async submit(ev) {
let {token} = await this.props.stripe.createToken({name: "Name"});
let data ={
id: token.id
}
let response = await fetch("/charge", {
method: "POST",
//Works with the commented code
//headers: {"Content-Type": "text/plain"},
//body: token.id,
headers: {"Content-Type": "application/json"},
body: JSON.stringify(data)
}).then(response => response.json());
if (response.ok) console.log("Purchase Complete!")
if (response.ok) this.setState({complete: true});
}
render() {
if (this.state.complete) return <h1>Purchase Complete</h1>;
return (
<div className="checkout">
<p>Would you like to complete the purchase?</p>
<CardElement />
<button onClick={this.submit}>Send</button>
</div>
);
}
}
export default injectStripe(CheckoutForm);
This is my server code:
const app = require("express")();
const stripe = require("stripe")("sk_test_oE2EqjsM7mWqgRRwaomptrdX");
app.use(require("body-parser").text());
app.post("/charge", jsonParser, async (req, res) => {
try {
var userdata = JSON.parse(req.body);
let {status} = stripe.customers.create({
description: "Test Person",
//Commented code currently works
//source: req.body
//Below is how I expected this to work when passing the body as JSON
source: userdata.id
});
res.json({status});
} catch (err) {
res.status(500).end();
}
});
app.listen(9000, () => console.log("Listening on port 9000"));
Related
On my API I created the endpoint http://XX.XXX.XX.XX/api/v1/endpoint
which receives this string :
{
"user": "RANDOM USER",
"url": "RANDOM URL",
"keyWord": "RANDOM KEYWORD"
}
and returns a result.
It works GREAT on postman but on the frontend part of the project I'm getting an error, and I can't seem to figure out why.
At first I thought that it has something to do with authentication but I changed the API so there is no need to be signed in anymore, but it still doesn't work on the react project. (works in postman though).
This is the error:
This is the frontend code:
import axios from 'axios';
const user = "RANDOM USER";
const url = "RANDOM URL";
const keyWord = "RANDOM KEYWORD";
const test = async () => {
const details = JSON.stringify({
user,
url,
keyWord,
});
try {
await axios
.get('http://XX.XXX.XX.XX/api/v1/endpoint', details, {
headers: {
'Content-Type': 'application/json',
},
})
.then((res) => {
console.log(JSON.stringify(res.data));
})
.catch((err) => {
if (err.response) {
// console.log(details); //WORKS
console.log(err.response.data.error);
}
});
} catch (e) {
console.log(e);
}
This is the backend code:
exports.test = catchError(async (req, res, next) => { //catchError is an outer function with try-catch, it catches errors and it works fine
const { url, keyWord } = await req.body;
const response = await axios.get(url);
const html = await response.data;
res.status(200).json({
status: 'success',
data: {
'XXXX'
}
});
Any ideas? Please help!
I'm scratching my head at this problem, I'm implementing Instagrams basic display API using Wix's new editor-x. My code works if I run it on the client side, I get an access token, however it doesn't when I import the getAccessToken function from the server side, the function runs but I get an invalid auth code.
I think there maybe an issue passing the code variable?
frontend code:
import wixLocation from 'wix-location'
import {getAccessToken} from 'backend/instagram'
let query = wixLocation.query; //get auth code from URL param
let code = query.code
console.log(code) //check code is correct
if(code){
const token = await getAccessToken(code) //request accesstoken
console.log(token) //log token
}
backend code:
import {fetch} from 'wix-fetch'
export async function getAccessToken(code) {
const url = "https://api.instagram.com/oauth/access_token"
const options = {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: `client_id=id&client_secret=secret&grant_type=authorization_code&redirect_uri=uri&code=${code}`
}
try {
const data = await fetch(url,options)
const token = await data.json()
return token
} catch(error) {
return error
}
}
Hello I am trying to post login details to my back end using axios, when I try it on Postman it works fine but when I do it through my front end I receive error 422
I am using fast API as my backend, a colleague is building it not me
I am using React as my frontend
here is my code:
import React, { Component } from 'react';
import'./login.css';
import axios from 'axios';
class Login extends Component {
constructor(props){
super(props);
this.state = {username:'', password:''}
this.handlechange = this.handlechange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handlechange(e){
this.setState({[e.target.name] : e.target.value})
}
handleSubmit(e){
e.preventDefault();
const data = { username: this.state.username,
password: this.state.password};
axios.post('https://fastapi-aadil.herokuapp.com/login,
data, {headers: {'Content-Type': 'application/x-www-form-urlencoded'}}
)
.then(res => {
console.log(res);
console.log(res.data)
})
.catch(err => {
console.log(err.response);
});
}
render()
the error I Receive
xhr.js:210 POST https://fastapi-aadil.herokuapp.com/login 422 (Unprocessable Entity)
I am not sure where I am doing it wrong I have tried and changed almost everything but it doesn't seem to work.
Thanks
You cannot use application/x-www-form-urlencoded like this with axios. See below on how to use it with axios.
handleSubmit(e){
e.preventDefault();
const data = new URLSearchParams()
params.append('username', this.state.username)
params.append('password', this.state.password)
axios.post(
'https://fastapi-aadil.herokuapp.com/login',
data,
{
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}
)
.then(res => {
console.log(res);
console.log(res.data)
})
.catch(err => {
console.log(err.response);
});
}
As #Tobi said in the previous answer that I can't use x-www-form-urlencoded I searched on axios docs on how to use it with react
it turned out we must use qs to stringify the data when making a post request.
and here is my code it worked fine.
handleSubmit(e){
e.preventDefault();
const values = {'username': this.state.username,
'password':this.state.password
}
const data = qs.stringify(values)
axios.post('https://fastapi-aadil.herokuapp.com/login',
data, {headers: {'Content-Type': 'application/x-www-form-urlencoded'}}
)
.then(res => {
console.log(res);
console.log(res.data)
})
.catch(err => {
console.log(err.response);
});
I have made a LitElement that is supposed to console log all users in a database. I do this with nodejs and mysql. I am able to get the users from the database and console.log them, but the script that fetches the data runs on repeat which it should not do. This is my LitElement.
export class AllUsers extends LitElement{
static get properties(){
return {
users : {type : String},
numberOfUsers : {type : Number},
location : {type: Object} // Needed for vaadin-router with litElements
}
}
constructor(){
super();
this.location = router.location
}
static styles = css`
:host {
display: block;
}
`;
render(){
return html `
<h1>ALL USERS</h1>
${this.getUsers()}
`;
}
getUsers(){
fetch('http://localhost:8081/getUsers', {
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
}
}).then(res =>{ res.json().then(data =>{
this.users = data
console.log(this.users)
this.numberOfUsers = this.users.length
})
}).catch((e) =>{
throw Error(e)
})
}
}
customElements.define('all-users', AllUsers)
nodejs app
app.get('/getUsers', function (req, res) {
db.query('SELECT * FROM users', function (err, result) {
if (err) {
res.status(400).send('Error in database operation.');
} else {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(result));
}
});
});
What would have to be changed to fix this?
This template:
return html `
<h1>ALL USERS</h1>
${this.getUsers()}`;
Renders the output of this.getUsers() into the template, but that's a void, so it basically just fires the function again each time it's rendered.
There are a couple of different approaches here - I'd recommend using guard and until to only get the users when some property changes, or adding a ReactiveController that fetches and caches users, but simplest is probably to just render the users and then kick off the script to get them.
Firstly change the template to render the users:
return html `
<h1>ALL USERS</h1>
${this.users?.map(u => html`<span>User: ${u.name}</span>`)}`;
Then simplify your getUsers to just populate it (note this is also a lot simpler with async/await):
async getUsers() {
if(this.users)
return; // We already have users, don't get again
const res = await fetch('http://localhost:8081/getUsers', {
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
}
};
this.users = await res.json();
console.log(this.users);
this.numberOfUsers = this.users?.length;
}
Then call this.getUsers() in either firstUpdated or connectedCallback.
Im trying to update my states after a form submit , without refreshing the page.
part of my ReactJs code :
export default class DashboardRA extends Component {
constructor(props)
{
super(props);
this.state = {
json:JSON.parse(props.data),//data received from a laravel controller used to implement the page.
pdf: '',
...
...
async onSubmitButton(e) {
e.preventDefault();
const formData = new FormData();
formData.append("pdf", this.state.pdf);
...
const response = await axios.post("/uploadFile", formData, {
headers: {
"Content-Type": "multipart/form-data"
}
})
.then(function (response) {
// console.log(response.data); //data from the DB
this.setState({
json:JSON.parse(response.data)
});
})
.catch(err => {
console.log(err);
this.setState({errorMessage: err.message});
})
}
but it shows the following error : Cannot read property 'setState' of undefined
Just change your code to
.then((response) => {
// console.log(response.data); //data from the DB
this.setState({
json:JSON.parse(response.data)
});
})
You're gwtting the error because when you refer to this in function you refer to whatever context this function is called in (some Promise internals). By using arrow syntax you're automatically binding it to the context it's declared in (component in your case)
It will be because your trying to acces to a method which is no defined in your response function. You have to assign this to variable before running axios. please check this out
export default class DashboardRA extends Component {
constructor(props)
{
super(props);
this.state = {
json:JSON.parse(props.data),//data received from a laravel controller used to implement the page.
pdf: '',
...
...
async onSubmitButton(e) {
e.preventDefault();
const formData = new FormData();
formData.append("pdf", this.state.pdf);
...
const my_this = this;
const response = await axios.post("/uploadFile", formData, {
headers: {
"Content-Type": "multipart/form-data"
}
})
.then(function (response) {
// console.log(response.data); //data from the DB
my_this.setState({
json:JSON.parse(response.data)
});
})
.catch(err => {
console.log(err);
my_this.setState({errorMessage: err.message});
})
}