here I have an ajax request that gets the photo of a random cat
import React, { Component } from 'react';
class RandomCat extends React.Component {
constructor(props) {
super(props)
this.state = {}
this.fetchRandomCatImg = this.fetchRandomCatImg.bind(this)
}
componentDidMount() {
this.fetchRandomCatImg()
}
fetchRandomCatImg() {
fetch("https://aws.random.cat/meow")
.then(response => response.json())
.then(data => {
this.setState({
error: null,
ready: true,
src: data.file
})
})
.catch(error => this.setState({ error }))
}
render() {
if (this.state.error) return <p>Oops, something went wrong!</p>
if (!this.state.ready) return <p>Loading...</p>
return <img src={this.state.src} className="cat" alt="random cat photo" />
}
}
export default RandomCat;
here we need to make a qr image code that links to the same photo that gets generated from that call
it means we need to pass data resulted from the cat api to the other ajax call that gets the qr code
I tried doing this but it gave another photo(new one)
import React, { Component } from 'react';
class QR extends React.Component {
constructor(props) {
super(props)
this.state = {}
this.fetchQR = this.fetchQR.bind(this)
}
componentDidMount() {
this.fetchQR()
}
fetchQR() {
fetch("https://qrtag.net/api/qr_12.svg?url=https://aws.random.cat/meow" )
.then(response => response.json())
.then(data => {
this.setState({
error: null,
ready: true,
src: data.file
})
})
.catch(error => this.setState({ error }))
}
render() {
if (this.state.error) return <p>Oops, something went wrong!</p>
if (!this.state.ready) return <p>Loading...</p>
return <img className="QR"src={this.state.src} alt="qrtag"/>
}
}
export default QR;
This is a bit different but you can use this package:
https://www.npmjs.com/package/qrcode.react
And then you only need to do one API call. Once the URL of the file is in your state, you display the QR Code like this:
<QRCode value={this.state.src} />
But if you still want to use the QR code generator API, you need to pass the URL of the cat you just fetched to this component, the value of data.fetch (this.state.src).
If you pass it https://aws.random.cat/meow of course it won't work.
Related
What I want is, when I get no data from the api, instead of this No data, I want A notification or toast.error to get displayed.
shops.jsx
import React from 'react';
import './shops.css';
import Shop from './shop'
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
require('dotenv').config()
const TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI1ZjFiMjNlYTQxNmJhMjQ3YjQ5MDk4Y2IiLCJlbWFpbCI6Img1aW1icjQ0NGQ7QHR5cC5pbiIsImlhdCI6MTU5NjgxMTU5MSwiZXhwIjoxNTk2ODE1MTkxfQ.UyrUkbNWzenf50FL8AZE1iZaii11P7MwdXpKmoCB9nM";
class Shops extends React.Component {
constructor(props) {
super(props);
this.state = {
shops: []
};
}
componentDidMount() {
console.log(process.env.REACT_APP_BaseURL);
// replace with correct URL: http://localhost:5000/api/shops/allShops
fetch(process.env.REACT_APP_BaseURL, {
method: "get",
headers: new Headers({
Authorization: `Bearer ${TOKEN}`
})
})
.then(response =>response.json())
.then(data => {
this.setState({ shops: data.fetchedShops });
toast.success("API LOADED SUCCESSFULLY","SUCCESS");
})
.catch(err =>{
console.log("Error", err);
if(err){
toast.error("error occured");
}
});
}
render() {
const shops =
this.state.shops.length > 0 ?
this.state.shops.map(item => (
<Shop name={item.shopname} address={item.address} mobile={item.phoneNumber} />
))
: <span >No data</span>;
console.log(this.state.shops);
return <div id="container">{shops}</div>;
}
}
export default Shops;
In the 6th line you can see <span >No data</span> instead of this I want a toast.error notification, but when I write toast.error("No data"); instead of this span i got something like this instead of error notification
If you want to toast that there is no data when the array is empty it needs to be done in two steps since render is a pure function, i.e. without side effects
Issue toast side-effect in component lifecycle functions, i.e. componentDidMount and/or componentDidUpdate
Render null when toasting no data, or since the map can handle empty arrays without issue, just return the empty map result array
Code
class Shops extends Component {
state = {
shops: []
};
checkShops = () => {
const { shops } = this.state;
if (!shops.length) {
toast.error("No Data");
}
};
componentDidMount() {
this.checkShops(); // not really needed if fetch for data first
}
componentDidUpdate() {
this.checkShops();
}
render() {
const { shops } = this.state;
return (
<div id="container">
{shops.map((item) => <div>Data</div>)}
</div>
);
}
}
I've finally figured out how to get data from the API :) but now I am stuck because I am trying to change the URL of a fetch request.
I can't figure out how to use my input in the URL as it brings up an error saying input not defined. Which I am assuming is because technically it is not linked. Am I overlooking something really simple?
Also a little background; I am trying to build a simple dictionary web application where you type in a word and it retrieves definitions. I am currently using the WordAPI API for my project.
import React from "react";
import "./App.css";
import ZipForm from "./ZipForm.js";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
items: null,
isLoaded: false,
input: "",
};
this.onFormSubmit = this.onFormSubmit.bind(this);
}
onFormSubmit(input) {
this.setState({ input });
}
componentDidMount() {
const url = `https://wordsapiv1.p.rapidapi.com/words/${input}/definitions`
fetch(url, {
method: "GET",
headers: {
"x-rapidapi-host": "wordsapiv1.p.rapidapi.com",
"x-rapidapi-key": "58143f60a0msh9b238a4cf58ba29p1e28e0jsn9e523b0104ba",
},
})
.then((response) => response.json())
.then((json) => {
this.setState({
items: json,
isLoaded: true,
});
console.log(json.definitions[0].definition);
});
}
render() {
var { isLoaded, items } = this.state;
if (!isLoaded) {
return <div>Loading...</div>;
} else {
}
return (
<div>
<h1 className="tc">{items.definitions[0].definition}</h1>
<ZipForm onSubmit={this.onFormSubmit} />
</div>
);
}
}
I believe URL should be
`https://wordsapiv1.p.rapidapi.com/words/${this.state.input}/definitions`
I am new to the react and I am learning how to HTTP get request using axios. I am referring to a youtube video: https://www.youtube.com/watch?v=NEYrSUM4Umw and following along, but I got an error. I think I have minor error but I can't figure it out.
import React, { Component } from 'react'
import axios from 'axios'
class PostList extends Component {
constructor(props) {
super(props)
this.state = {
posts: []
}
}
componentDidMount(){
axios.get('https://api.particle.io/v1/devices/64646468431646/temperature?access_token=547376a1b2')
.then(response => {
console.log(response)
this.setState({posts: response.data})
})
.catch(error => {
console.log(error)
}
)
}
render() {
const { posts } = this.state
return (
<div>
temperature
{
posts.length ?
posts.map(post => <div key={post.coreInfo.deviceID}> {post.result} </div>) :
null
}
</div>
)
}
}
export default PostList
When I use postman to get a HTTP request, I get the following response:
{
"cmd": "VarReturn",
"name": "temperature",
"result": "67.55",
"coreInfo": {
"last_app": "",
"last_heard": "2020-04-05",
"connected": true,
"last_handshake_at": "2020-04-05",
"deviceID": "64646468431646",
"product_id": 8
} }
My goal is to display the result: 67.55 in the web application.
Thank you in advance
If you're only getting a single object as the response from your fetch instead of an array, just wrap it in an array -
this.setState({posts: [response.data]})
I am trying to fetch some data from an API through a POST request, then I would like to display those data on the browser, but I am encountering this problem:
Line 30: Expected an assignment or function call and instead saw an expression
My code looks like this:
import React, { Component } from "react";
import axios from "axios";
class GetData extends Component {
componentDidMount() {
axios
.post(
`https://api.multicycles.org/v1?access_token=API_KEY`,
{
query:
"query ($lat: Float!, $lng: Float!) {vehicles(lat: $lat, lng: $lng) {id type attributes lat lng provider { name }}}",
variables: { lat: 52.229675, lng: 21.01223 }
}
)
.then(response => {
console.log(response);
this.setState({
data: response.data
});
})
.catch(error => {
console.error(error);
});
}
render() {
console.log(this.state.data);
return (
<ul className="filter-options">
{this.state.data.data.map(val => {
<p>{val.templateFields}</p>;
})}
</ul>
);
}
}
export default GetData;
I would like then, to render in App.js a component called <GetData /> and display the results from the API, but I'm still getting the error previously mentioned.
Where I'm doing something wrong?
I'm not sure where you're getting
this.state.data.data
from. You're setting
this.setState({
data: response.data
});
so I would expect something like
this.state.data.map(...)
I also don't see a constructor for your component - you need to set default, state, for example
constructor(props) {
super(props);
this.state = {date: new Date()};
}
You're not returning anything in your map try :
<ul className="filter-options">
{this.state.data.data.map(val => (
<p>{val.templateFields}</p>
))}
</ul>
Also you need a default state in your component.
i am new in react js,and i am learning to create a React application and I got a problem with mapping function:
Here's my request and how I am attempting to render the data:
class Patients extends Component {
constructor(props) {
super(props)
this.state = {
patients: []
}
}
componentDidMount() {
api.getPatients()
.then( patients => {
console.log( patients)
this.setState({
patients: patients
})
})
.catch(err => console.log(err))
}
render() {
return (
<div className=" Patientss">
<h2>List of Patient</h2>
{this.state.patients.map((c, i) => <li key={i}>{c.name}</li>)}
</div>
);
}
}
export default Patients;
here my api calling
import axios from 'axios';
const service = axios.create({
baseURL: process.env.NODE_ENV === 'production' ? '/api' : 'http://localhost:3000/patient',
});
const errHandler = err => {
console.error(err);
throw err;
};
export default {
service: service,
getPatients() {
return service
.get('/')
.then(res => res.data)
.catch(errHandler);
},
}
and I get the following error:
TypeError: this.state.patients.map is not a function
i've try to use slice aswell but it didnt work, anyone know whats wrong with my code?`
Based on the symptoms (heh), the patients object you get in api.getPatients() isn't an array.
console.log() it to see what it actually is.
EDIT: Based on the comments, the patients object looks like
{
count: 24,
patient: [...],
}
so the this.setState() call needs to be
this.setState({patients: patients.patient})
You can also do something like this as an conditional rendering. It will check that if this.state.patient exists then only it will go ahead and call this.state.patients.map function. It will also ensure that you don't receive any errors later on due to bad responses.
I updated your Patients Code example.
class Patients extends Component {
constructor(props) {
super(props)
this.state = {
patients: []
}
}
componentDidMount() {
api.getPatients()
.then( patients => {
console.log( patients)
this.setState({
patients: patients
})
})
.catch(err => console.log(err))
}
render() {
return (
<div className=" Patientss">
<h2>List of Patient</h2>
{ this.state.patients && this.state.patients.map((c, i) => <li key={i}>{c.name}</li>)}
</div>
);
}
}
export default Patients;
I hope it helps. Thanks!!