Failed call to Deezer API with React and axios - reactjs

I want to connect to Deezer API and read data, the API is available here, if you take first links they have there and open in a new tab you will see the data in json, however Axios can't return it
import React from "react";
import ReactDOM from "react-dom";
import axios from "axios";
import "./styles.css";
class App extends React.Component {
componentDidMount() {
axios.get("https://api.deezer.com/album/302127")
.then(response => {
console.log(response);
})
.catch(err => {
console.log(err);
});
}
render() {
return (
<div className="App">
<h2>Deezer</h2>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Deezer api don't allow cross-origin request. So an api call from browser is not possible.
However you can use a workaround and use https://cors-anywhere.herokuapp.com
You need to change your code like following:
axios.get("https://cors-anywhere.herokuapp.com/https://api.deezer.com/album/302127")
.then(response => {
this.setState({ response })
})
.catch(err => {
console.log('error', err);
});
Here is a working example: https://stackblitz.com/edit/react-v6bufu
However, I will recommend to code your own backend where you will call
Deezer's APIs. You won't be getting cross-origin error there.

Related

Fetch data from GET request

When I call my API via my web browser I get the following result:
{"statusCode": 200, "body": "\"Cheers from AWS Lambda!\""}
However, I am now struggeling to show body via axios. Do you see what I am doing wrong?
import axios from "axios";
import React, { Component } from "react";
class App extends Component {
state = {
messages: []
};
componentDidMount() {
axios
.get(
"https://12345.execute-api.eu-central-1.amazonaws.com/prod/get-data"
)
.then(response => {
const messages = response.data;
this.setState({ messages });
});
}
render() {
return (
<ul>
{this.messages}
Test
{this.state.messages.map(message => (
<li>{message}</li>
))}
</ul>
);
}
}
export default App;
A few points:
1) Change this.messages in ul of render method to this.state.messages, as this.messages is undefined.
2) A good practice while using JSX is to keep js and html code as distinguishable as possible, so the map on a list should be done outside the return statement.
const listItems = numbers.map((number) =>
<li>{number}</li>
);
return (
<ul>{listItems}</ul>
);
3) For more info about CORS error and how to rectify it while using AWS lambda, refer to this article which includes a code snippet: AWS: CORS

Using Redirect upon form submission in React

I have been attempting to Redirect upon user login. The login works correctly with my database and will conditionally render my new links for my admin portal. I was trying to use Redirect upon getting a status code 200, but I am not sure if this is even the correct way.
axios post for Login component:
const handleSubmit = e => {
e.preventDefault();
console.log(adminLogin)
axios
.post("/api/Authentication", adminLogin)
.then(function(response) {
if (response.status === 200) {
setIsLoggedIn(true);
<Redirect to="/inventory" />
}
setAdminLogin(response.data);
console.log(response);
})
.catch(function(error) {
console.log(error);
});
You can't Redirect from function directly. If you want to redirect from function then you can use this.props.history.push('/inventory');
And another way to redirect using state.
const[login,setIsLoggedIn]=useState(false)
if (response.status === 200) {
setIsLoggedIn(true);
}
if(login){
return <Redirect to='/inventory'/>
}
return(
//Main function return
);
if you use react-router-dom you can see this example from documentation and you can see similiar question in here
As it is an axios call, it is always recommended to use this.props.history.push().
Make sure while using this function, you have already used withRouter to route your component.
import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';
import axios from 'axios';
class App extends Component {
...
const handleSubmit = e => {
e.preventDefault();
console.log(adminLogin)
axios
.post("/api/Authentication", adminLogin)
.then(function(response) {
if (response.status === 200) {
setIsLoggedIn(true);
this.props.history.push('/inventory');
}
setAdminLogin(response.data);
console.log(response);
})
.catch(function(error) {
console.log(error);
});
}
...
}
export default withRouter(App);
If you won't wrap your component with withRouter, history object will not be present in this.props and hence, will be throwing an error.

React native connect to laravel passport api and receive access token

I set up the backend with Laravel and passport and everything goes correctly when I use postman but when I use Axios in React native app it gives me an error and doesn't load any response
React code:
import React , { Component } from 'react';
import {View , Text} from 'react-native';
import axios from 'axios';
class Lapi extends Component {
state = {
url: 'http://laravelinstallation/api/user'
};
componentWillMount(){
this.getUserInfo();
}
render(){
return(
<View>
<Text>Test</Text>
</View>
);
};
getUserInfo(){
axios.get(this.state.url)
.then(response =>
console.log(response.data)
)
.catch(err =>
console.log(err)
)
}
}
export default Lapi;
Use your IP-address: http://192.168.x.x/laravelinstallation/public/api/user
You can get it by running ipconfig (Windows) or ifconfig (Mac/Linux)

HTTPS error on deployed React project

I was trying to host my React project on GH Pages. The deploy worked fine but when I try to search for gifs I get the following error
http_browser.js:47 Mixed Content: The page at
'https://pimmesz.github.io/react-giphy/' was loaded over HTTPS, but
requested an insecure XMLHttpRequest endpoint
'http://api.giphy.com/v1/gifs/search?
q=h&limit=10&rating=g&api_key=MYAPIKEY'. This request has been blocked; the
content must be served over HTTPS.
It seems like the Giphy API is making a http request instead of https. Is there a way to change the default url which the API uses?
import React, { Component } from 'react';
import giphy from 'giphy-api';
import Search from './search.jsx';
import Gif from './gif.jsx';
import GifList from './gif_list.jsx';
class App extends Component {
constructor(props) {
super(props);
this.state = {
gifs: [],
gif: "xBoysJgwhLEZtAjbY1"
}
}
search = (query) => {
giphy('APIKEY').search({
q: query,
limit: 10,
rating: 'g'
}, (err, res) => {
this.setState({gifs: res.data})
});
}
select = (id) => {
this.setState({gif: id})
}
render() {
const gifs = this.state.gifs;
return (
<div>
<div className="left-scene">
<Search search={this.search}/>
<Gif id={this.state.gif} select={this.select} />
</div>
<div className="right-scene">
<GifList gifs={gifs} select={this.select} />
</div>
</div>
);
}
}
export default App;
Changed the giphy API execution to
const url = `https://api.giphy.com/v1/gifs/search?q=${query}&limit=10&rating=g&api_key=MY_API_KEY`
fetch(url)
.then(results => { return results.json();
}).then(data => {
this.setState({gifs: data.data});
});
EDIT
Found another way!
Setting https to true can be done as an option in the giphy api call
giphy({ apiKey: "MY_API_KEY", https: true })

How to redirect in axios?

Can I redirect in .then instead of console.log?
axios
.post('/api/users/login', user)
.then(res => console.log(res.data))
.catch(err => this.setState({ errors: err.response.data }))
Is it possible and if it is how can I do it?
I would suggest that you should not perform side operations inside the actions (in this case axios call). This is because you would eventually add these calls inside redux thunk/saga or some other middleware.
The pattern which I follow is you return the promise and add the redirection logic inside your components(or containers). Following are the benefits of it:-
It makes your code cleaner and avoids side affects inside your API calls.
It makes easier to test your API calls using mock data.
Showing alert in case the API fails without passing callback as function parameter.
Now, that being said you can use the above logic in following ways:-
// Component code
import { browserHistory } from 'react-router';
class TestContainer extends React.Component {
auth = () => {
login()
.then(() => {
browserHistory.push("/addUser");
})
.catch(() => {
// Show alert to user;
})
}
render () {
return (
<div>
<button onClick={this.auth}>Auth</button>
</div>
);
}
}
// Action code
const login = () => {
return axios
.post('/api/users/login', user);
}
U can use: location.window.href
Usually I use react-router to redirect
history.js
import createHistory from 'history/createBrowserHistory';
export default createHistory()
Root.jsx
import { Router, Route } from 'react-router-dom'
import history from './history'
<Router history={history}>
<Route path="/test" component={Test}/>
</Router>
another_file.js
import history from './history'
history.push('/test') // this should change the url and re-render Test component
Ref: https://github.com/ReactTraining/react-router/issues/3498
Your question is not about reactjs or axios, its just pure javascript.
Use location.href

Resources