Error: Network error on Axios API call - reactjs

I am working with the CryptoCompare API to get data about cryptocurrencies for my project. I've made a few requests to the API and have had no issue getting a response.
Some of the queries for the API look like this:
https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=BTC,USD,EUR
And others look like this:
https://www.cryptocompare.com/api/data/coinsnapshot/?fsym=BTC&tsym=USD
When I make requests to URLs that look like the first I am able to get a response from the API and retrieve the data. When I make the same request but for one of the URLs that look like the second I get an error. Error: Network error is all it says.
Here's what my code looks like:
import React, { Component } from 'react';
import axios from "axios";
class CoinInfo extends React.Component {
constructor(props) {
super(props);
this.state = {
coinInfo: []
}
}
componentDidMount() {
axios.get(`https://www.cryptocompare.com/api/data/coinsnapshot/?fsym=BTC&tsym=USD`)
.then(res => {
const info = res.data;
this.setState({ coinInfo: info});
console.log(info);
});
}
render() {
return (
<div className="container">
</div>
)
}
}
export default CoinInfo;
If I swap out the URL in the Axios request and replace it with the other API endpoint/URL it works perfectly fine. It also works fine with any of the other CryptoCompare endpoints that have the root "min-api.cryptocompare.com".
However all the endpoints that follow the "www.cryptocompare.com/" pattern don't work.
I am not getting a CORS error. Just an error that says "Error: Network error" in Firefox.
Is this a problem with the API itself? Or is there something on my end I am overlooking?

axios.get(`https://www.cryptocompare.com/api/data/coinsnapshot/?fsym=BTC&tsym=USD`)
its incorrect format I think so please retype it as
axios.get("https://www.cryptocompare.com/api/data/coinsnapshot/?fsym=BTC&tsym=USD")

Related

Reactjs, CORS errors while making post request using axios

I am using React.js 18 version. Facing CORS issue on a piece of code while making post request using axios. Intentionally not putting the original URL of post request. Attaching API response screenshot files below the code.
I am getting response in postman but not in browser(CORS). All I know from my colleague, this API is build on PHP and according to backend guy things are fine on his side.
I am putting this code here to know what are we doing wrong on front end? We are stuck here since yesterday.
Please help!
console response : https://i.stack.imgur.com/HbUjq.png
network response : https://i.stack.imgur.com/6xycq.png
network response : https://i.stack.imgur.com/5cjey.png
postman response : https://i.stack.imgur.com/MxyDT.png
import React, {useState, useEffect} from 'react';
import axios from 'axios';
import './App.css';
function App() {
const [CaseDetail, setCaseDetail] = useState([]);
const getCaseDetail = async () => {
const casedetail = {schemeNameDratDrtId:'1',casetypeId:'1',caseNo:'1',caseYear:"2020"};
await axios.post('URL', casedetail,
{
headers: {"Access-Control-Allow-Origin": "*"}
}
)
.then((result) => {
setCaseDetail(result.data.data)
})
}
useEffect(() => {
getCaseDetail();
}, []);
console.log(CaseDetail)
return (
<div className="App">
<h2>Welcome to Home Page</h2>
</div>
);
}
export default App;
Your server should enable the cross-origin requests, not the client. To do this, you can check this nice page with implementations and configurations for multiple platforms
This is a security issue from the browser. If you get 200 using postman, this means the problem is that the browser is blocking it. Try to play this again using API testing website like: "reqbin.com", if that works, the backend guys should fix the header problem. I hope this helps.
some possiable things that might help:
I am getting response in postman but not in browser(CORS) - this is noraml for CORS problem.
there can be a differnce betweeen fetach and axios requests. so check if fetach works. if so check
Axios fails CORS but fetch works fine
if you need to send a token in a header , make sure that the axios sends it
see
How to set header and options in axios?

Keycloak acts as if its uninitialized after a hard page refresh

First of all, thanks in advance to anyone who reads my question and comments. I have a CRA app that is using keycloak-js and ReactKeycloakProvcer from `#react-keycloak/web. When you first load the application page and login, keycloak is initialized correctly and functions as it should. The provider gets an instance of KC in a pretty standard way.
import keycloak from './authentication/keycloak'
const KeycloakProviderBlock = ({children}) => {
return (
<ReactKeycloakProvider authClient={keycloak} initOptions={{onLoad: 'login-required'}}>
{children}
</ReactKeycloakProvider>
);
};
Later in my axios wrapper, I am pulling the KC token out to add to all requests as the bearer token like this:
import keycloak from "./authentication/keycloak";
const {authenticated} = keycloak;
if (authenticated) {
client.defaults.headers.common = {
...client.defaults.headers.common,
Authorization: `Bearer ${keycloak.token}`,
};
} else {
logger.error("Request client used before KeyCloak initialized");
}
My keycloak file just returns a new instance of KC --> contents of /authentication/keycloak.js
import Keycloak from "keycloak-js";
const keycloak = new Keycloak({
realm: process.env.REACT_APP_KEYCLOAK_REALM,
url: process.env.REACT_APP_KEYCLOAK_URL,
clientId: process.env.REACT_APP_KEYCLOAK_CLIENT,
})
export default keycloak
Everything works like it should until the user hard refreshes the page. When the page reloads keycloak.authenticated is not present on the KC object, so all HTTP calls fail because there is no Bearer token.
I'm using keycloak-js version 15.0.2. Any/all thoughts appreciated.
I figured out how to fix this and figured I would post the answer in case it helps anyone else. It turns out when the page refreshes, it takes KC longer to restore the session information from the cookie than it does for the code to run. So there was a race condition when the page reloaded it was trying to reach the backend before KC had a chance to validate the user was indeed logged in. It turns out that the KeycloakProvider emits events and tells you when the token is refreshed. The events were not firing because I had the KCProvider wrapped in a JSX component, so the events were not properly bound. I removed the unnecessary block and the events started to fire. From there, it was pretty easy to display a Loading throbber and block the rest of the components from rendering until the provider actually got the onReady event. The new code looks like this:
In App.js
// Keycloak
onKeycloakEvent = (event, error) => {
console.log('onKeycloakEvent', event, error)
console.log(`Keycloak Event ${event}`);
if(event && event === 'onReady'){
this.setState({keycloakReady: true})
}
}
onKeycloakTokens = (tokens) => {
console.log('onKeycloakTokens', tokens)
}
...
In the Render Pass the functions to the provider:
<ReactKeycloakProvider authClient={keycloak} initOptions={{onLoad: 'login-required'}}
keycloak={keycloak}
onEvent={this.onKeycloakEvent}
onTokens={this.onKeycloakTokens}>
<SplashScreen keycloakReady={keycloakReady}>
....
</SplashScren>
</ReactKeycloakProvder>
Then in the SplashScreen only render children if KC is ready:
import React, {Component, PureComponent, ReactChildren} from "react";
import LoadingSpinner from "../navigation/LoadingSpinner";
type PassedProps = {
keycloakReady: boolean;
}
class SplashScreen extends PureComponent<PassedProps, any> {
constructor(props: PassedProps) {
super(props);
}
render() {
console.log(`SplashScreen keycloak ready ${this.props.keycloakReady}`);
if(!this.props.keycloakReady){
return <LoadingSpinner/>
}else{
return this.props.children
}
}
}
export default SplashScreen

Pattern for a React component with access to lowdb

I am looking for a pattern for a react component. It should include lowdb. Someone already build one?
Okay, I dont access the lowdb by frontend. I use Axios to send a request to my node/express backend and respond with the lowdb-data. Requires you know how to interact with a react frontend and a node/express backend on different ports. I dont let express render my react-app... looks something like this and axios as a dependency in the package.json + import Axios from 'axios':
export default class Status extends Component {
constructor(props) {
super(props);
this.state = "";
}
componentWillMount() {
Axios.get("http://localhost:4000/dbUserAuth").then((res) => {
let authState = res.data;
if (authState) {
this.setState({ authState });
}
});
}
This sends a request to my node.js/express backend which runs on port 4000. The frontend runs on 2000.
The backend can look something like this:
server.get("/dbUserAuth", (request, response) => {
function resAuthData() {
let array = [];
const dbUserAuth = db.get("UserAuth[0]").value();
const dbChatIdFound = db.get("UserAuth[1]").value();
const botActive = db.get("UserAuth[2]").value();
array.push(dbUserAuth, dbChatIdFound, botActive);
response.send(array);
}
resAuthData();
});
Hopefully someone needs theese snippets.
best regards

axios response doesn't filled

I'm making react app which search on Youtube and show some list of video by using create-react-app.
My problem is the document of response from axios.get() only contains scripts and empty skeleton tag.
I want this has some contents inside of it like when opened from browser. why this happen? and what should i study?
import React from "react";
import SearchBar from "./SearchBar";
import axios from "axios";
class App extends React.Component {
onSubmitFormSearch = async (text) => {
console.log("axios", text);
const response = await axios.get(`/results?search_query=${text}`, {
responseType: "text",
responseEncoding: "utf8",
});
console.log(response.data);
};
render() {
return <SearchBar onSubmitForm={this.onSubmitFormSearch} />;
}
}
export default App;
this is my react code
here's document of response https://codepen.io/im0505/pen/MWaMKXa
You will not get the complete webpage just like you see in browser when visualising the response of axios.get. The fundamental reason is that when you load an URL in browser, browser executes the scripts from the response of the request which doesn't happen when visualising response of request made by axios.
What Happens When You Type in a URL : Source
You enter a URL into a web browser
The browser looks up the IP address for the domain name via DNS
The browser sends a HTTP request to the server
The server sends back a HTTP response
The browser begins rendering the HTML
The browser sends requests for additional objects embedded in HTML (images, css, JavaScript) and repeats steps 3-5.
Once the page is loaded, the browser sends further async requests as needed.
Points 6 and 7 doesn't happen when you are looking at the result in Codepen or in your axios response

ReactJS error - “Cannot read property 'data' of undefined”

I’m building a React form that will have several drop-down boxes populated with data from MongoDB. I’m relatively new to React and a beginner with MongoDB.
I’m starting with just trying to create a basic page with one drop-down on it. Once I get that right, I can move on to adding the other drop-downs.
I’ve been able to successfully get the data into the drop-down by just cramming all of the code into one file. Now, I’m trying to start refactoring the code by properly splitting pieces into separate files. And that’s where I’m running into problems.
I’ve split out my MongoDB data pull (using Mongo Stitch) into a separate “service” file. And I’m still getting data through that new service file. But when I then try to pull that service-file data into my main (App.js) page, I’m getting a “Cannot read property 'data' of undefined” error. So, clearly, the way I’m trying to pull the data into my App.js file is wrong. I’d appreciate any expert insights anyone could offer!
Here’s my App.js file –
import React, { Component } from "react";
import "./App.css";
import { getProjects } from "./services/svcProjects";
class App extends Component {
state = {
data: {
selProject: ""
},
Projects: []
};
async componentDidMount() {
await this.fetchProjects();
}
async fetchProjects() {
const { data: projects } = await getProjects();
console.log(projects);
this.setState({ projects });
}
render() {
return (
<div className="App">
<h1>Project Log</h1>
<label htmlFor={"selProject"}>{"Project"}</label>
<select name={"selProject"} id={"selProject"} className="form-control">
<option value="" />
{this.state.projects.map(a => (
<option key={a._id} value={a.project}>
{a.project}
</option>
))}
</select>
</div>
);
}
}
export default App;
And here’s the “projects service” file. Again, please note that the console.log statements here show that I’m still getting data back from MongoDB. I’m just not pulling the data into my App.js file the right way.
Also, by the way, I realize that having my Mongo connection info in this file is a huge security hole. I’ll be fixing that later.
import {
Stitch,
RemoteMongoClient,
AnonymousCredential
} from "mongodb-stitch-browser-sdk";
export function getProjects() {
const client = Stitch.initializeDefaultAppClient("------");
const db = client
.getServiceClient(RemoteMongoClient.factory, "-----")
.db("----------");
client.auth
.loginWithCredential(new AnonymousCredential())
.then(() =>
db
.collection("--------")
.find({}, { sort: { Project: 1 } })
.asArray()
)
.then(res => {
console.log("Found docs", res);
console.log("[MongoDB Stitch] Connected to Stitch");
return res;
})
.catch(err => {
console.error(err);
});
}
It looks like you're using destructuring to get the data member from an object returned by getProjects(), but getProjects() doesn't return an object with such a member.
Perhaps you'd like to change it to something like the following -
async fetchProjects() {
const projects = await getProjects();
console.log(projects);
this.setState({ projects });
}
Also, like #Win mentioned, the P in projects is capitalized in your state initialization but not afterwards. You might wanna fix that.
I've discovered that my problem boils down to the fact that my data isn't arriving in the componentDidMount lifecycle hook soon enough. So, by the time the process moves on, the "projects" data is still undefined. In other words, my "async / await" isn't . . . awaiting!
I'll be posting a separate question about how I can make that async wait until I actually get the data back. But again, just wanted to mark this as "solved" because the problem isn't happening downstream from the data fetch. The data simply isn't arriving soon enough.

Resources