Return multiple variables Flask -> React - reactjs

I have a request from a React frontend to a Flask backend, where the backend calculates a bunch of stuff, and then I try to return two Pandas data frames.
So basically the return of my backend looks like:
return df1.to_json(orient="records"), df2.to_json(orient="records")
My frontend fetches data by:
const [data, setData] = useState([])
function fetchData(e) {
e?.preventDefault();
POST("/data_fetch", {}).then(async (response) => {
const json = await response.json();
setData(json);
});
}
where POST is just:
function POST(path, data) {
return fetch(`${fetchUrl}${path}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: accessToken,
},
body: JSON.stringify(data),
});
}
The issue is that this only returns the first variable, i.e. df1 from the return. And If I try to do something like:
return jsonify(df1_data=df1.to_json(orient="records"), df2_data= df2.to_json(orient="records"))
and then:
setData({df1Data: json.df1_data, df2Data: json.df2_data});
The resulting jsonified output is just formatted very badly. And if I remove the to_json() then it can't jsonify it at all.
So is there any way to fix this ? The issue is that the data frames created are based on some of the same data, which needs to be fetched from another API, so that call/calculation takes a few seconds. So if I were to split it up, and do it twice (one for each data frame), that just seems like a waste of time.

Related

What needs to be done in the useMutation hook in order for the returned result to have 'symbol.iterator'?

I am going tgrough the repo that Tanner used when illustrating react query functionality and its benefits. Basically I am doing it step by step in line with the order of his commits in this repo. However when I reached the stage of migrating to using react-query from using useEffect and regular fetching mechanisms I got stuck with the following error
Type 'UseMutationResult<void, unknown, void, unknown>' must have a
'Symbol.iterator' method that returns an iterator.
This error occurs when I am trying to use a custom hook useCreateTransaction. Implementation of this custom hook looks like following:
import { useMutation, useQueryClient } from "react-query";
export default function useCreateTransaction() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (values) => {
const res = await fetch("/api/transactions", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(values),
});
// const data = await res.json();
// return data;
},
onSuccess: (data) => {
queryClient.invalidateQueries("transactions");
// return [createTransaction]
},
});
}
What I tried to do: to assign returned values of this hook by way of destructuring like so
const [createTransaction, { status: createTransactionStatus }] =
useCreateTransaction();
I was expecting to use createTransaction to mutate the state on server but instead am seeing this error
Type 'UseMutationResult<void, unknown, void, unknown>' must have a
'Symbol.iterator' method that returns an iterator.
I am not sure if this is helpful: I am using astrobuild for the client and planetscale as the db and cloudflare functions as the backend. Here is the link to the repo
const [createTransaction, { status: createTransactionStatus }] =
useCreateTransaction();
this is the v2 api. The video is almost 2.5 years old. Concepts are still relevant, but apis have changed. Latest version is v4, where it is:
const { mutate: createTransaction, status } =
useCreateTransaction();
You're getting that error because you're trying to destruct something as an array that isn't an array.

NextJS - request with large JSON object

I do have a NextJS application where I make a request to the api route using fetch
const options = {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(filesForImport),
};
const response = await fetch("api/import", options);
quite straightforward.
The catch here, is that the body is a "large" JSON object, with about 6500 lines (as per Postman).
This makes the request to completely hang, I don't see the api/import route to be called at all, and if I check the developer tools/Network I do see the request pending, and never resolves.
If I send a small json with 20 lines, all works as needed, so is defenetelly something with NextJS handling large JSON objects.
I did try to change the config for that route
export const config = {
api: {
bodyParser: false,
},
};
but it doesn't help.
For testing sake, the route doesn't do any logic, commented it all.
export default async (req: NextApiRequest, res: NextApiResponse) => {
console.log(99999)
try {
const files: LocalizationImportData[] = req.body;
console.log(888, files)
//await some logic here, which is commented
res.status(200).end();
} catch (err: unknown) {
if (err instanceof Error) console.error(`failed to import records: ${err.stack}`);
res.status(500).send(err);
}
};
in the case of small payloads, I do see the 99999 in the console, with large requests nothing happens.
I tried to make the requests via Postman, from Edge and Chrome browsers, all behave the same, the request just hangs forever.
The overall file size of that JSON payload is about 200kb, pretty small I'd say.
What else can be changed here?

How to pass a JSON data from React to Django using POST request?

I have a React frontend which has a state variable that contains an array. I want to pass this state variable onClick to my Django's views.py. What I have so far is something like this:
App.js
const [dataSource, setDataSource] = useState([]); // Where the data is stored in
const requestOptions = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(dataSource),
};
const handleSubmit = () => {
fetch("http://localhost:8000/insert", requestOptions);
};
<Popconfirm onConfirm={handleSubmit}>
<Button>Submit</Button>
</Popconfirm>
views.py
def insert(request):
if request.method == 'POST':
json_data = request.POST.get()
# I'm not sure what should I be putting as a parameter for .get() method
return render(request, 'frontend/index.html')
urls.py
...
urlpatterns = [
...
path('insert/', views.insert),
...
]
Am I using the right approach? If it's right, what should I be passing as parameters to the get() method?
*P.s. I'm not using DRF for this approach and I'm building the app where Django and React is in one app (not separate) where the frontend is an app of Django.
Couple of things before the problem. First you should not use insert as your view name its against the rest conventions, for more read this doc
Second make it fetch("http://localhost:8000/insert/", requestOptions);
Third when you want to get the body all you need to do is
import json
data = json.loads(request.body)
and you will get the post data as json in your hand

Axios post request with formData

I want to make a form with multiple input (two text and one image).
Furthermore, I'm using react, axios, formik and I submit my data to strapi.
With only one text and one file, it works fine, but when I try to add a new append, I've got the error
When using multipart/form-data you need to provide your data in a JSON 'data' field.
const onSubmit = async (event) => {
const data = new FormData()
//This works
data.append('data', JSON.stringify({title:event.title}))
data.append('files.cover', file)
//This doesnt
data.append('title', JSON.stringify({title:event.title}))
data.append('description', JSON.stringify({description:event.description}))
data.append('files.cover', file)
try{
const response = await axios.post('http://localhost:1337/foodtrucks', data,
{
headers: userToken && { Authorization: `Bearer ${userToken}` }
},
)
// const data = await response.json()
console.log("response", response)
} catch(err){
// setError(err.response.data.message[0].messages[0].message)
setError("error")
console.log(err)
}
}
I tried to add headers, to use form-data, etc. Nothing works.
I think axios is meant for calling APIs - it may not be easy (or possible to send form data).
If you're running in the Browser, you may want to use plain XMLHttpRequest. I came across this article, which defines the submitForm function. It has helped me a lot on many projects.

Why am I getting empty array in fetch request to MongoDB from ReactJS?

I am trying to fetch all the articles from a document in MongoDB in React. It is perfectly working in Backend with NodeJS when I tested with Postman. But in Frontend , React, I am getting empty array. How to solve this.
Server.js (Backend)
app.get('/api/articles', async (req, res)=>{
const client = await MongoClient.connect('mongodb://localhost:27017', {useNewUrlParser:true, useUnifiedTopology:true})
const db = client.db('my-blog')
const articleInfo= await db.collection('articles').find({}).toArray(function(err, result){
if (err) console.log(err)
res.status(200).send(result)
client.close()
})
})
articlePage.js (FrontEnd)
componentDidMount(){
const requestOptions = {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
};
const fetchdata = fetch('/api/articles/').then(res=>res.json())
.then(data=>this.setState({articles:data}))
console.log(this.state.articles)
}
Api address is set up in package.json with proxy:http://localhost:8000
How to get the documents data from MongoDB in React?
Firstly, check if you the API call went through to the server from your React app. If it has, then check for the response code in the network. In your case, 200 is where you get the desired result from the API. If you are not getting the desired result, then check your collection and document names and also arguments your are passing in the query.
As setState is not synchronized, you have to access it in the callback.
this.setState({ articles: data }, () => {
console.log(this.state.articles)
})

Resources