Routing Problem in calling API from REACT using Redux - javascript

I have create api with Python (django restframework). I am calling that api from my react applicaation using redux.
It works fine when i call it like this
const {data} = await axios.get(`http://127.0.0.1:8000/api/products/${id}`)
but when i change the url to
const {data} = await axios.get(`api/products/${id}`)
It then makes a request to a different route ( http://localhost:3000/product/api/products/6) and I want it to make a call to (http://localhost:8000/api/products/6
I have added the path in django server and allowed calls from the react app. and it is working perfectly when i was working with other routes.
for example it was working fine when i was making call to this route
const {data} = await axios.get('api/products/')

You need to give the url to the api. If you don't provide full url, it will add your react app url.
You can declare a variable with the route
API_URL = "http://localhost:8000/"
const {data} = await axios.get(`${API_URL}api/products/${id}`)

module.exports = {
//...
devServer: {
proxy: {
'/api': {
target: 'http://127.0.0.1:8000',
changeOrigin: true,
},
},
},
};
Add the above configuration to your webpack,then the request can be forwarded by wepack dev server.
more details,please visit https://webpack.js.org/configuration/dev-server/#devserverproxy

Related

setupProxy.js not getting called in React app

I'm playing around with a React front-end for an app I want to build and I'm pretty new to React. I've been trying to run it with a Flask backend and have watched a variety of YouTube videos to guide me, but I've been stuck with this same issue for a couple hours now. I have a proxy pointing to my Flask backend, but the proxy never gets used.
Here is my setupProxy.js as instructed from the Create React App documentation:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
console.log("hello"); //extra print statement that never gets logged
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
})
);
};
Here is my get code that I stole from a video:
function App(){
const [data, setData] = useState(null);
function getData(){
axios({
method: "GET",
url: "/api",
})
.then((response) => {
const res = response.data;
setData(({
name : res.name,
age : res.age
}))
}).catch((error) => {
if(error.response){
console.log(error.response);
console.log(error.response.status);
console.log(error.response.headers);
}
})
}
...
I've updated my package.json and played around with different get calls, but they all seem to lead to the same issue. When I run my app, the setupProxy.js never seems to get run. The request is always sent to "http://localhost:3000/api" and I even have an extra console.log statement that never gets run. Am I missing something? Any help would be greatly appreciated. <3

How can I fetch data from the host URL in getStaticPaths() in Next.js serverless function?

I have a Next.js app that uses a serverless function to fetch data from its host. The host URL is stored in a .env file and is set to http://localhost:3000/api/data for dev and https://productionurl.com/api/data for production.
However, for testing purposes, I have hosted the app on Vercel, and the testing URL will be randomly generated, such as https://randomvercelurl_abcd1234.com/api/data.
I can use ctx or req to get the host URL in the getServerSideProps method, as shown in the example code below:
export async function getServerSideProps({query, req}){
const API_URL = req.protocol + req.headers.host + "/api/data"
const res = await axios.get(API_URL)
...
}
The problem arises in the getStaticPaths method, where I need to fetch data to generate dynamic routes. I don't have any way to get the host URL in this method, as demonstrated in the following example code:
export async function getStaticPaths() {
const host = ???
const res = await fetch(`${host}/api/data`)
const posts = await res.json()
const paths = posts.map((post) => ({
params: { id: post.id },
}))
return { paths, fallback: false }
}
How can I access the host URL in the getStaticPaths method to fetch data?
You cannot get a ctx with host like in getServerSideProps because getStaticPaths runs at build time. So the URL from which you want to fetch data should be fully known, either in the code or through an environment variable.
getStaticPaths will only run during build in production, it will not be called during runtime. You can validate code written inside getStaticPaths is removed from the client-side bundle with this tool.
The solution is to add the randomly generated URL into your environment variable on Vercel, or wherever you host your app. You may also want to read when should I use getStaticPaths.

CORS proxy error in react app and express server

I am running a React app with an Express server back-end on port:5000. I am making a request to one of my endpoint using the state of the element to get some data and then render it to the page. I initially setup the proxy in the package.json file of the React app as "proxy": "http://localhost:5000" (documentation. Now it was giving me a proxy error saying cannot proxy to localhost:5000. So I used CORS in my express server as a universal middleware for all of the routes using app.use(cors()).That removed the proxy error but the request is still not working (the code is not even reaching the endpoint because nothing is being logged to the console) and I am pretty sure it's because of the same error. Here are the code snippets
router.get("/", async (req, res) => {
var elements = [];
elements = await Element.find();
res.json(elements);
});
const getElements = async () => {
try {
console.log('getElements call')
const data = await axios.get("/api/elements");
console.log(data);
dispatch({ type: GET_ELEMENTS, payload: data });
} catch (e) {
console.error(e);
}
};
const { getElements, elements, loading } = elementContext;
useEffect(() => {
getElements();
}, [])
Expected behaviour: I want the endpoint to send an array name elements to the call which can then be set to the elements state using the reducer and then can be accessed by destructing in the end. I hope I have given adequate information. Any help will be appreciated. Thank you.

React / Redux and Swagger client

I'm trying to figure out the best way to structure a React / Redux app that will primarily use a swagger client for api access.
The problem is I'm not entirely sure where to store a reference to the swagger client. After logging in and obtaining a JWT auth token, I need to tell all subsequent requests to add the authorize header. With axios this is trivial because it persists it's headers until told otherwise. It doesn't appear the swagger client does this. So ideally, I would create a swagger client once upon login, add the header info and just reference it for all future requests (that way too it only fetches the schema json once in a single page application).
Since I'm doing this in the context of an action, would it be best to store the Swagger client in the Redux store (and how would I accomplish that)? Or would I create a static instance of it outside of Redux?
// app init
const createStoreWithMiddleware = applyMiddleware(promise)(createStore);
const store = createStoreWithMiddleware(reducers);
export const swaggerClient = { instance: authService.createFromState().then(() => {
ReactDOM.render(
<Provider store={store}></Provider>
...
);
});
do some login stuff, create swagger client:
// redux action
import { swaggerClient } from '../index';
// ... do login, get bearerToken
Swagger({
url: 'https://localhost/swagger/v1/swagger.json',
requestInterceptor(req) {
req.headers['Authorization'] = `Bearer ${bearerToken}`;
return req;
}
}).then((client) => {
// store reference for all future ajax calls
swaggerClient.instance = client;
});
and in case the page is refreshed, we need to rebuild the swagger client from the bearerToken in local storage
// authService
import { swaggerClient } from '../index';
function createFromState() {
// if authentication is known from localstorage, we can rebuild
// a swagger client
if(isAuthenticated()) {
const authentication = getAuthentication();
return Swagger({
url: 'https://localhost/swagger/v1/swagger.json',
requestInterceptor(req) {
req.headers['Authorization'] = `Bearer ${authentication.bearerToken}`;
return req;
}
}).then((client) => {
swaggerClient.instance = client;
return client;
});
}
}
I'm a little confused if this is the right direction, probably a newbie question. Having to wait for the swagger client to load while restoring from localstorage seems a kinda crazy way to do this (to prevent race conditions on future calls).

How to pass Request cookies through node-fetch in isomorphic app?

I'm trying to build isomorphic project using React, Express and isomorphic fetch (based on whatwg-fetch on client and node-fetch on server), from this common boilerplate. I'm using cookies for my access token, and credentials: 'same-origin' on front-end side to send it to GraphQL -- works pretty well.
The problem is that I can't use the same solution for server side -- node-fetch just don't support using of XMLHttpRequest cookies from the box. My fetch request is under few abstract layers from router, so I can't just use cookie value from req.
Here is my server.js code (full version):
server.get('*', async (req, res, next) => {
try {
// some presettings here..
await Router.dispatch({ path: req.path, query: req.query, context }, (state, component) => {
data.body = ReactDOM.renderToString(component);
});
res.send(template(data));
} catch (err) {
next(err);
}
});
and Route's index.js (full version):
export const action = async (state) => {
const response = await fetch('/graphql?query={me{id,email}}', {
credentials: 'same-origin',
});
const { data } = await response.json();
// ...
return <Login title={title} me={data.me} />;
};
How can I pass my token from server.js to my fetch module? Or, maybe there are some better decisions?
First off, I hope you have found an answer by now!
Secondly, cookies are really just headers. If you need to send a cookie to authorize server-side requests, you can always just create the string that you need for the cookie value and send it as a header.
For an example, take a look at how this server-side node-fetch wrapper appends saved cookies to the outbound request: https://github.com/valeriangalliat/fetch-cookie/blob/master/index.js#L17

Categories

Resources