How to pass value to Koa2 - reactjs

I have an react app that I want to pass value down to a koa server.
let data = new FormData()
data.append('json', JSON.stringify(token))
fetch('/charge', { method: 'POST', body: data })
.then((res) => {
return res.json()
})
.then((json) => {
console.log('something wrong')
console.log(json)
})
and below is my server code
const config = require('../config')
const server = require('../server/main')
const router = require('koa-router')()
const parse = require("co-body")
const port = config.server_port
server.use(router.routes())
router
.post('/charge', function (ctx, next) {
console.log(ctx.request.body)
console.log('howyd')
ctx.body = "howdy"
})
Just can't get the value passing down from client. Do you guys know what is going on?

Make sure you're using the body parser. It looks like you're requiring it in, but not actually using it. Something like this (untested):
const config = require('../config')
const server = require('../server/main')
const router = require('koa-router')()
const parse = require("co-body")
const port = config.server_port
server.use(router.routes())
router
.post('/charge', async (ctx, next) => {
let body = await parser.json(ctx.request)
console.log(body)
console.log('howyd')
ctx.body = "howdy"
})

Related

State Not Finished Setting before being used in useEffect

I am hosting a react app in aws amplify using the aws-serverless version of express as the REST API, which sits inside of a lambda function. A big problem that I am facing is that asynchronous jobs in aws-serverless express cause the lambda function to complete before the promises resolve. Leaving me with no data and no error handling. This caused me to bring a lot of the asynchronous work to the front end of the application.
The problem here is that I need to bring a large amount of data into state. Right now, I am using a delay workaround (shown below) but instead need a programatic way to make sure state is finished updating before being used in the second useEffect hook (dependent on odds & failedTries props) instead of using the delay functionality.
Any help would be greatly appreciated.
const App = ({ signOut }) => {
const [odds, setOdds] = useState([]);
const [updateTime,setUpdateTime] = useState(0);
const [failedTries,setFailedTries] = useState(0);
useEffect(() => {
const setNflOdds = async () => {
let response = await updateNflOdds();
let data = response;
setOdds(data);
};
setNflOdds();
setUpdateTime(1);
const interval = setInterval(() => {
setNflOdds();
setUpdateTime(updateTime => updateTime +1);
}, 100000);
return () => clearInterval(interval);
}, []);
useEffect(() => {
const s3Push = (() => {
if(!odds.length) {
setFailedTries(failedTries => failedTries + 1);
} else {
const delay = ms => new Promise(res => setTimeout(res, ms));
const nflOddsRefDelay = async() => {
*//This is the current workaround, wait ten seconds before pushing odds state up to the s3 bucket*
await delay(10000);
oddsS3Helper(odds);
};
nflOddsRefDelay()
}
});
s3Push();
}, [odds, failedTries]);
With the above indicated delay workaround this works for my use case (13k records inside of the array) but the data size is highly variable and I want to figure out a way that no matter the data size it brings the entire call up to the s3 bucket.
below is the content of the functions being called in the useEffect hook
const pushToS3 = async ( file, key ) => {
const creds = await Auth.currentCredentials()
const REGION = {region};
const s3Client = new S3Client({
credentials: Auth.essentialCredentials(creds),
region: REGION
});
const params = {
Bucket: {s3 bucket name}
Key: key,
Body: file,
};
s3Client.send(new PutObjectCommand(params));
console.log("file is sent");
};
const oddsS3Helper = (async (odds) => {
console.log("inside s3 helper: ",odds);
let csv = '';
let headers = Object.keys(odds[0]).join(',');
let values = odds.map(odd => Object.values(odd).join(',')).join('\n');
csv += headers + '\n' + values;
const buffedFile = csv;
const key = 'nflprops.csv'
const delay = ms => new Promise(res => setTimeout(res, ms));
const propRefDelay = async() => {
await delay(5000);
await postNflOdds();
};
pushToS3( buffedFile, key );
await propRefDelay();
});
async function getNflGames() {
const apiName = {name of serverless API inside of lambda};
const path = {path name};
const init = {
headers: {} // OPTIONAL
};
const data = await API.get(apiName, path, init);
return data;
};
async function getNflOdds(gameId) {
const apiName = {name of serverless API inside of lambda};
const path = {path name};
const init = {
headers: {}, // OPTIONAL
body: { gameId }
};
const data = await API.post(apiName, path, init);
return data;
};
async function updateNflOdds() {
const ojNflGames = await getNflGames();
const nflGameProps = [];
const nflOddsPush = ( async () => {
try {
await ojNflGames.data.map( async (game) => {
const ojNflOdds = await getNflOdds(game.id)
await ojNflOdds.data[0].odds.map((line) => {
nflGameProps.push(
{
gameId: game.id,
oddsId: line.id,
sports_book_name: line.sports_book_name,
name: line.name,
price: line.price,
checked_date: line.checked_date,
bet_points: line.bet_points,
is_main: line.is_main,
is_live: line.is_live,
market_name: line.market_name,
home_rotation_number: line.home_rotation_number,
away_rotation_number: line.away_rotation_number,
deep_link_url: line.deep_link_url,
player_id: line.player_id,
}
);
});
});
} catch (err) {
console.log("there was an error", err);
}
});
try {
await nflOddsPush();
} catch(err) {
console.log("odds push errored: ", err);
}
console.log("inside of updateNflOdds function: ",nflGameProps);
return nflGameProps;
};

React Axios - Pass Hook as Parameter for Axios Params

I am new to React & Axios, I'm trying to work my head around how to change the GET instance properties based on user inputs... If I am going about it the wrong way please direct me.
I want the selected dataFormat to pass to the params of the Axios.getData()
At the moment I can only get it to pass the object rather than its value.
Thanks in advance
Here is the code to fetch the data:
function App() {
let [responseData, setResponseData] = React.useState([]);
const [dataFormat, setDataFormat] = React.useState("json");
const fetchData = (e) => {
e.preventDefault();
console.log({dataFormat});
api
.getData(dataFormat)
.then((response) => {
console.log("Hello");
console.log(response);
setResponseData(response.data);
})
.catch((error) => {
console.log(error);
});
};
Here is the Axios instance
enter image description here
Here is the error I am receiving:
enter image description here
First you need to install the express library. Then, import cors and also use express.json() for parsing the json as shown below:
const express = require("express");
const app = express();
const cors = require("cors");
app.use(express.json());
app.use(cors());
function App() {
let [responseData, setResponseData] = React.useState([]);
const [dataFormat, setDataFormat] = React.useState("json");
const fetchData = (e) => {
e.preventDefault();
console.log({dataFormat});
api
.getData(dataFormat)
.then((response) => {
console.log("Hello");
console.log(response);
setResponseData(response.data);
})
.catch((error) => {
console.log(error);
});
};

Pass data from reactjs to koajs server(405 method not allowed)

I'm a beginner at both ReactJS and KoaJS.
I'm trying to send data from my React js form inputs to the server-side which was written with Koa.
Here is what I wrote to post data to the backend.
app.js
const FormContainer = () => {
const url = "http://localhost:3100/"
const [data,setData] = useState({
email:"",
firstname:"",
lastname:""
})
function submit(e){
e.preventDefault();
Axios.post(url, {
email: data.email,
firstname: data.firstname,
lastname: data.lastname
})
.then(res => {
console.log(res.data)
})
}
function handle(e){
const newData = {...data}
newData[e.target.id] = e.target.value
setData(newData)
console.log(newData);
}
Here is the server-side code
server.js
const Koa = require('koa');
const json = require('koa-json');
const KoaRouter = require('koa-router');
const bodyParser = require('koa-bodyparser');
const { default: App } = require('next/app');
const cors = require('#koa/cors');
const port = 3100
const server = new Koa();
const router = new KoaRouter();
server.use(json());
server.use(cors());
router.get('/', ctx => (ctx.body = {
}));
server.use(router.routes());
server.use(router.allowedMethods());
server.listen(port, () => console.log('Server Running'));
When I run the server, I keep getting this console error but I'm not sure what's wrong. Can someone help me? Thank you.
Error Image

Adding multiple API calls to a map in reactjs using axios

I need my API call to pull NFT data from moralis and add it to a map so it can later be rendered.
This all works fine, however the limit per call on moralis is 100 lines. I have added a second API call using cursor pagination. Both API calls work individually but when I try to add both to the map it just renders the most recent one. Is there a way to show everything in the collection? Thanks in advance!!
Here is the code I currently have to call the API:
async function callApi() {
var provider = await web3Modal.connect();
web3 = new Web3(provider);
await provider.send('eth_requestAccounts');
var accounts = await web3.eth.getAccounts();
account = accounts[0];
vaultcontract = new web3.eth.Contract(VAULTABI, STAKINGCONTRACT);
let config = { 'X-API-Key': moralisapikey, 'accept': 'application/json', cursor: '' };
const nfts0 = await axios.get((moralisapi + `nft/${NFTCONTRACT}/owners?chain=polygon&format=decimal&limit=100`), { headers: config })
.then(output => {
const { result } = output.data
return result;
})
const nfts1 = await axios.get((moralisapi + `nft/${NFTCONTRACT}/owners?chain=polygon&format=decimal&limit=100`), { headers: config })
.then(output => {
const { result } = output.data
return result;
})
const nfts = (nfts0, nfts1)
const apicall = await Promise.all(nfts.map(async i => {
let item = {
tokenId: i.token_id,
holder: i.owner_of,
wallet: account,
}
return item
}))
const stakednfts = await vaultcontract.methods.tokensOfOwner(account).call()
.then(id => {
return id;
})
const nftstk = await Promise.all(stakednfts.map(async i => {
let stkid = {
tokenId: i,
}
return stkid
}))
getNfts(apicall)
getStk(nftstk)
console.log(apicall);
setLoadingState('loaded')
}

Fastify giving a react prop to a render with next.js

I am using Next.js's example server with Fastify and experimenting with it and am wondering if there is a way to pass let's say a JSON object as a prop into a render? I've tried to find anything in the documentation and can't find anything for doing this.
The server code I'm using is this,
const fastify = require('fastify')();
const Next = require('next');
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
fastify.register((fastify, opts, next) => {
const app = Next({ dev })
app.prepare().then(() => {
fastify.get('/', (req, res) => {
let object = {"hello": "world"}; // object I want to pass as a prop
return app.render(req.req, res.res, '/index', req.query).then(() => {
res.sent = true
})
})
next()
}).catch(err => next(err))
})
fastify.listen(port, err => {
if (err) throw err
console.log(`Ready on http://localhost:${port}`)
})
Your question is not specific to Fastify, but relevant for all server frameworks.
The basic idea is that req & res object are passed to Next's getInitialProps.
So you can put your data on them.
For example, express's Response object has locals attribute that is specific to this job.
So, in order to pass data attach it to req / res.
fastify.get('/', (req, res) => {
const object = { hello: 'world' }; // object I want to pass as a prop
res.res.myDataFromController = object;
return app.render(req.req, res.res, '/index', req.query).then(() => {
res.sent = true;
});
});
// some next page.jsx
const IndexPage = ({ dataFromGetInitilProps }) => (
<div> {JSON.stringify(dataFromGetInitilProps, null, 2)} </div>
);
IndexPage.getInitilProps = ctx => {
const { res } = ctx;
// res will be on the context only in server-side
const dataFromGetInitilProps = res ? res.myDataFromController: null;
return {
dataFromGetInitilProps: res.myDataFromController,
};
};
export default IndexPage;

Resources