pulling data from another domain, react and api platform - symfony - reactjs

Working locally, I'm trying to pull some data from an api endpoint into a react front-end. Here's what I have:-
Data source/api endpoint (api platform, symfony)
http://127.0.0.1:8000/api/users?page=1
Front-end, React
http://127.0.0.1:3000/
/src/App.js
import React from 'react';
fetch('http://127.0.0.1:8000/api/users?page=1')
.then(response => console.log(response))
.then(json => console.log(json))
function App() {
return (
<div className="App">
</div>
);
}
export default App;
Firstly, I had to overcome a CORS issue with my data source. In symfony;-
.env
###> nelmio/cors-bundle ###
CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
###< nelmio/cors-bundle ###
As a side note; For my api endpoint (data source) - I can return the json response fine using both cURL and postman. However, if I try directly in a browser address bar, I just get my api landing page back i.e. swagger doc.
I'm wondering if this is an issue with headers not being set?
Back in my react app http://127.0.0.1:3000/ and at the console;-
my response is showing a 200 as you can see from above, but my json variable has a length of zero? So, no data.
Any ideas on how to pull the data (json) through to my react app using the above technique?

Here's what I was looking for in the end...
import React from 'react';
import { useEffect } from 'react'
function App() {
useEffect(() => {
fetch("http://127.0.0.1:8000/api/users?page=1")
.then((response) => response.json())
.then((response) => {
console.log(response);
})
}, []);
return (
<div className="App">
</div>
);
}
export default App;

Related

Error when trying to call flask API from react app

So im getting the following error;
Uncaught (in promise) SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON
I have googled this, and there are tonnes of people with this problem, and lots of solutions, however, non seem to work for me, or im implementing them incorrect...
Scenario - React app trying to call data from a Flask API.
Flask API code
app = Flask(__name__)
#app.route("/authURL")
def home():
data = {
"AuthURL":"www.google.com",
"test123":123
}
return jsonify(data)
React code
import { useEffect } from 'react';
function App() {
useEffect(() => {
fetch("/authURL")
.then(response => response.json()
.then(data => {
console.log(data)
})
)}, []);
return (
<div className="App">
<header className="App-header">
</header>
</div>
);
}
export default App;
The network suggests there is no issue with communicating between flask and react, ive tried to isolate the problem, and it seems to be with the data itself, but honestly not sure.
Any help is appreciated!
Thanks in advance

How Do I Call An Authenticated HTTP Trigger Google Cloud Function Via A Next.js (with Typescript) App?

I created a Google Cloud Platform account, and made a simple hello_world type Python "Cloud Function" that just spits out some simple text. I made this function "HTTP" accessible and only able to be called/authenticated by a "Service Account" that I made for the purpose of calling this very function. I generated a key for this "Service Account" and downloaded the json file for the key.
The problem is that I can't find any documentation on how to call this function with my service account in a next.js app. I tried this:
import React from 'react';
import { Button } from 'react-bootstrap';
import { GoogleAuth } from 'google-auth-library';
const projectId = 'gtwitone';
const keyFilename = '/Users/<myusername>/path/to/cloudfunction/credentials.json';
class Middle extends React.Component {
handleClick() {
console.log('this is:', this);
}
// This syntax ensures `this` is bound within handleClick. // Warning: this is *experimental* syntax. handleClick = () => { console.log('this is:', this); }
/* async listFunctions() {
const [functions] = await client.listFunctions();
console.info(functions);
} */
async runGoogleCloudFunctionTest() {
// Define your URL, here with Cloud Run but the security is exactly the same with Cloud Functions (same underlying infrastructure)
const url = "https://us-central1-<projectname>.cloudfunctions.net/<functionname>"
//Example with the key file, not recommended on GCP environment.
const auth = new GoogleAuth({keyFilename: keyFilename})
//Create your client with an Identity token.
const client = await auth.getIdTokenClient(url);
const res = await client.request({url});
console.log(res.data);
}
render() {
return (
<div className="col-md-12 text-center">
<Button variant='primary' onClick={this.runGoogleCloudFunctionTest}>
Click me
</Button>
</div>
);
}
}
export default Middle;
But I got this error in my terminal:
<myusername>#<mycomputername> <thisnextjsappdirectory> % yarn dev
yarn run v1.22.17
$ next dev
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
wait - compiling...
event - compiled client and server successfully in 267 ms (124 modules)
wait - compiling / (client and server)...
wait - compiling...
error - ./node_modules/google-auth-library/build/src/auth/googleauth.js:17:0
Module not found: Can't resolve 'child_process'
Import trace for requested module:
./node_modules/google-auth-library/build/src/index.js
./components/Middle.tsx
./pages/index.tsx
https://nextjs.org/docs/messages/module-not-found
Native Node.js APIs are not supported in the Edge Runtime. Found `child_process` imported.
Could not find files for / in .next/build-manifest.json
Could not find files for / in .next/build-manifest.json
^C
<myusername>#<mycomputername> <thisnextjsappdirectory> %
I know that this is problem with server side rendering in my Next.js app and people recommend using a client side package like this https://github.com/google/google-api-javascript-client. But google-api-javascript-client doesn't have any documentation on authenticating with a .json credentials file instead of an API KEY which I do not have.
In short how do I get my app to work and run the Google Cloud function with a .json credentials file for am authenticated service account?
I fixed it by simply moving the GoogleAuth api call to the pages/api route.
pages/api/google.ts
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from "next"
import { GoogleAuth } from "google-auth-library"
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
const url = process.env.FUNCTION_URL as string
//Example with the key file, not recommended on GCP environment.
const auth = new GoogleAuth({ keyFilename: process.env.KEYSTORE_PATH })
//Create your client with an Identity token.
const client = await auth.getIdTokenClient(url)
const result = await client.request({ url })
console.log(result.data)
res.json({ data: result.data })
}
components/Middle.tsx
import React from "react"
import { Button } from "react-bootstrap"
class Middle extends React.Component {
handleClick() {
console.log("this is:", this)
}
// this talks with /pages/api/google
async imCallingAnAPI() {
const result = await fetch("/api/google")
console.log({ result })
}
render() {
return (
<div className="col-md-12 text-center">
<Button variant="primary" onClick={this.imCallingAnAPI}>
Click me
</Button>
</div>
)
}
}
export default Middle
pages/index.tsx
import type { NextPage } from 'next'
import Header from '../components/Header';
import Footer from '../components/Footer';
import Middle from '../components/Middle';
const Home: NextPage = () => {
return (
<><main className='d-flex flex-column min-vh-100'>
<Header />
<br></br>
<br></br>
<Middle />
</main>
<footer>
<Footer />
</footer>
</>
)
}
export default Home
I think that next.js has trouble loading GoogleAuth in a component. I'm not 100% sure why, but I think it has to do with next.js not knowing exactly how to handle GoogleAuth with server-side rendering.

Fetching data with the endpoint from AWS using React js

I am using axios to fetch data from aws.
import React, {useState, useEffect} from 'react';
import axios from 'axios';
function Employee() {
const[data, setData] = useState([]);
useEffect(() => {
axios.get('123.56.234.123:8080/employees?num=1')
.then(response => {
setData(response.data);
})
},[]);
return data;
}
From this code, I got the error message saying
Get http://localhost:8080/123.56.234.123:8080/employees?num=1 431(Request Header Fields Too Large).
I believe the cause is from the wrong url I am getting.
In this case, how can I fetch data from the endpoint?
PS) My node version: 14.XX
Thank you.
I think you need to set a PROXY. You have currently set the axios baseURL to be localhost:8080. That is why the get url is getting prepended to baseUrl.
The error 431(Request Header Fields Too Large) occurs because the Referrer url is too long.
If you are using create-react-app, then please refer this official documentation.

How to retrieve and display images in reactjs that are stored on the server side using multer and the path is stored in the database

I am having similar problem.I stored the path in database named Cast and the images on the server. The database has two fields name and image. In the react app,i want to display the image.I am not getting the image.
I am running express on localhost:5000 and reactjs on localhost:3000.
Ex: image in the db has the value "Anushka.jpg". On the server side it is stored as follows:
public
└─ cast_images
└─ Anushka.jpg
app.js file(server side)
app.use('/login', express.static(path.join(__dirname, '/public')));
app.get('/login',(req,res)=>{
Cast.find()
.then(
cast=>res.json(cast))
.catch(err => res.status(400).json('Error: ' + err));
});
App.js(frontend react file):
function App() {
return (
<Router>
<Navbar />
<br/>
<Route path="/login" component={Login}/>
</Router>
);
}
export default App;
Login.js
import React, { Component } from 'react';
import axios from 'axios';
export default class Login extends Component {
state={
casts:[]
};
componentDidMount() {
axios.get('http://localhost:5000/admin/')
.then(response => {
this.setState({casts:response.data});
console.log(response.data);
})
.catch((error) => {
console.log(error);
})
}
render() {
const actor =this.state.casts.map(actor => {
return (
<p>
<img src="/cast_images/{actor.image}" alt="hello"/>
<h3>{actor.name}</h3>
</p>
);
});
return(<p>{actor}</p>);
}
}
I did not not mention here imports in React code.This is a part of code.Can u please tell me how to get the image.Thanks in advance.
With this code you are mounting your public folder to the /login url path, I don't think that is what you want
app.use('/login', express.static(path.join(__dirname, '/public')));
So it should be changed to
app.use('/', express.static(path.join(__dirname, '/public')));
And in React, you can use JavaScript template string literal to insert a variable inside a string.
const serverBaseURI = 'http://localhost:5000' // set this to the value of your express server, should be different value for production server
/* .... */
<img src={`${serverBaseURI}/cast_images/${actor.image}`} alt="hello"/>

Create a Flask and React Full Stack Application

How do I create a website with a React Front end and a Flask backend?
I have created websites using flask and templates, and I have made pages using react, and now I would like to combine them.
I have tried a few things and the only things that worked required going into react config files and were very complicated. And even then it was complicated to use fetch and I had to run npm run build every time I changed the react file.
This seems to me like something that would be done all of the time yet I can't find any simple resources to do this.
Is there something that I fundamentally don't understand regarding websites and I am going at this the wrong way?
Focusing on a development workflow, as there are countless choices in how to deploy to a production environment.
Run your Flask app with /api as the root url prefix, either manually by prefixing all your route decorators or with the use of a Blueprint.
py/app.py
#app.route('/api')
def index():
return {'message':'hello'}
Add the Flask development server url to your package.json file
js/package.json
{
...,
"proxy": "http://localhost:5000"
}
Fetch your data using a component
js/Flask.js
import React, { Component } from 'react'
export class Flask extends Component {
constructor(props) {
super(props)
this.state = { data: {}, status: null }
}
fetchData() {
let status
fetch('/api')
.then((res) => {
return {
data: res.json(),
status: status
}
})
.then((data) => {
this.setState({ ...data })
}
.catch((err) => {
console.error(err)
})
}
componentDidMount() {
this.fetchData()
}
render() {
const { data, status } = this.state
return (
<div>
<h3>Status: { status }</h3>
<pre>
{ JSON.stringify(data) }
</pre>
</div>
)
}
}
export default Flask
Finally, include the component in your main App
js/App.js
import React from 'react';
import Flask from './Flask'
function App() {
return (
<div className="App">
<Flask />
</div>
);
}
export default App;
Start your Flask server with your preferred method, either flask run or by executing your script directly, then start your JS development server with either yarn or npm start. You should see the response from your api route displayed at http://localhost:8000
As long as you are running your Flask server with debug=True and use npm start (not npm run build), any changes made with either the backend or frontend will be automatically detected and your app reloaded.

Resources