Display data from state - reactjs

I have took data from firebase and want to display:
class DisplayVisit extends Component{
state = {
allVisit: [] //this I have changed
}
componentDidMount(){
this.getVisit();
}
getVisit = async() => {
try {
const currentVisit = await doctorvisit.get();
this.setState({ allVisit: currentVisit })
this.state.allVisit.forEach(element => {
console.log(element.data()) // i see data, fields like => {user, info, visitAt}
});
} catch(error) {
console.log('error getting visits ', error);
}
}
render(){
return(
{Object.keys(this.state.allVisit).map(key => (
<span>{this.state.allVisit[key].info}1</span>
))}
)
}
}
But nothing is render.
I tried also {key.info} but nothing is render.
Screen from console:
Log from console.log(this.state.allVisit);:

If i see good, you're setting the state allVisit to currentVisit, wich is a single object.
Either your allVisit property in state is an array with visit objects inside, or simply apply currentVisit in state as a single object.
In the meantime, you're looping a single object, if its what you're trying to achieve, remove the .info after the [key] and you will have all you're property displayed
If you want to loop through nested objects or an array of object provide more informations
Update, i'll tried to guess your data so try with this code
export default class DisplayVisit extends Component {
state = {
allVisit: [] //this I have changed
};
componentDidMount() {
this.getVisit();
}
getVisit = async () => {
try {
const { docs } = await doctorvisit.get();
//try this if first not working
const allVisitsData = await doctor.visit.get()
this.setState({ allVisit: docs });
//try this if first not working
//this.setState({ allVisit: allVisitData.docs });
//or this
} catch (error) {
console.log("error getting visits ", error);
}
};
render() {
return (
<div>
{this.state.allVisit.map((visit) => (
<span key={visit.info}>{visit.info} 1</span>
))}
</div>
);
}
}

I did it based on Google docs:
class DisplayVisit extends Component{
state = {
allVisit: []
}
componentDidMount(){
this.getVisit();
}
getVisit = async() => {
try {
await doctorvisit.get().then(querySnapshot => {
const data = querySnapshot.docs.map(doc => doc.data());
this.setState({allVisit : data});
})
} catch(error) {
console.log('error getting visits ', error);
}
}
}
Documentation:
https://firebase.google.com/docs/firestore/query-data/get-data?hl=en
and blog/post:
https://rnfirebase.io/firestore/usage

Related

Setting state object dynamically using the data returned using Promise.all and fetch API : React+Typescript

I am using fetch API and promise.all for a scenario where I am passing an array of URL'S from where I am fetching the data. The data retrieved from all the above URL'S needs to be set to the state object.
Say I have an array of 5 URL's , the result returned by these must be
assigned to the 5 different values inside my state object.
Using React along with typescript.
Help would be appreciated.
This is what I have tried so far
import * as React from 'react';
const urls = [ 'http://localhost:3001/url1',
'http://localhost:3001/url2',
'http://localhost:3001/url3',
]
interface IState {
test: [],
result: [],
returnVal: []
}
export default class App extends React.Component<{},IState> {
constructor(props:any)
{
super(props);
this.state = {
test: [],
result: [],
returnVal: []
}
checkStatus(response:any) {
if (response.ok) {
return Promise.resolve(response);
} else {
return Promise.reject(new Error(response.statusText));
}
}
parseJSON(response:any) {
return response.json();
}
setData(data:any){
Object.entries(this.state).forEach(([key], index) => {
this.setState({ [key]: data[index] })
});
}
componentDidMount()
{
Promise.all(urls.map(url =>
fetch(url)
.then(this.checkStatus)
.then(this.parseJSON)
.catch(error => console.log('There was a problem!', error))
))
.then(data => {
this.setData(data);
})
}
render() {
return(
//some rendering code
)
}
}
Need to set the data returned from promise to the state object variables.
Promise.all(urls.map(url =>
fetch(url)
.then(this.checkStatus)
.then(this.parseJSON)
))
.then(jsons => {
var newState = {};
var index = 0;
for(var key in this.state)
newState[key] = jsons[index++];
this.setState(newState);
})

Unable to access Api call data. Returns undefined. React

I am trying to make a movie search app with React and have made an API call to The Movie Database API. What I am trying to do is get the data of the new movie releases, but then make another API call to get the specific details for each of those new releases since that data is stored in a different location.
I am able to access the data from the first API call, but when I try to access the movie taglines from the second data object, the console outputs "Cannot read property 'tagline' of undefined".
App.js
class App extends Component {
constructor(props) {
super(props)
this.state = {
movieRows: [],
ids: [],
movieDetails: [],
}
this.performSearch = this.performSearch.bind(this);
}
componentDidMount() {
this.performSearch();
}
performSearch() {
const urlString = "https://api.themoviedb.org/3/movie/popular?api_key=6db3cd67e35336927891a72c05&language=en-US&page=1";
axios.get(urlString)
.then(res => {
const results = res.data.results
let movieRows = [];
let movieDetails = [];
results.forEach((movie) => {
movieRows.push(movie);
axios.get(`https://api.themoviedb.org/3/movie/${movie.id}?api_key=6db3cd67e35336927891a72c05&language=en-US`)
.then(res => {
movieDetails.push(res.data);
})
.catch(function (error) {
console.log(error);
});
});
this.setState({
movieRows: movieRows,
movieDetails: movieDetails,
});
})
.catch(function (error) {
console.log(error);
});
}
Content.js
export default class Content extends Component {
constructor(props) {
super(props)
this.state = {
name: 'Jonathan',
}
this.filmLoop = this.filmLoop.bind(this);
}
filmLoop() {
let movieData = this.props.globalState.movieRows;
let movieDetails = this.props.globalState.movieDetails;
return movieData.map((movie, index) => {
return (
<div className="film" key={index}>
<img className="poster" src={`http://image.tmdb.org/t/p/w342${movie.poster_path}`} alt="The Dark Knight poster" />
<div className="film-info">
<div className="film-title">
<h3>{movie.title}</h3>
</div>
<h4>{movieDetails[index].tagline}</h4>
*I get the error from the last line
Well the main issue is that you are calling setState outside your .then you have to update the state inside your then or your catch. This is because the promise is an async function, so you have to change the state only when the promise has been resolved of rejected.
performSearch() {
const urlString = "https://api.themoviedb.org/3/movie/popular?api_key=6db3cd67e35336927891a72c05&language=en-US&page=1";
axios.get(urlString)
.then(responsePopular => {
const results = responsePopular.data.results
let movieRows = [];
let movieDetails = [];
results.forEach((movie) => {
movieRows = [...movieRows, movie];
axios.get(`https://api.themoviedb.org/3/movie/${movie.id}?api_key=6db3cd67e35336927891a72c05&language=en-US`)
.then(responseMovie => {
movieDetails = [...movieDetails, responseMovie.data];
this.setState({
movieRows: movieRows,
movieDetails: movieDetails,
})
})
.catch(function (error) {
console.log(error);
});
});
})
.catch(function (error) {
console.log(error);
});
}
I think that this could solve your issue.

React Display Data from API Fetch & Map

i'm attempting to learn React by making a movie web app. Im trying to pull upcoming movies from a movie api, and display information from it, however i keep getting an error:
Line 37: Expected an assignment or function call and instead saw an
expression no-unused-expressions
Please excuse me as im not too familiar with this framework and im not a JS pro. Heres my code:
export default class Upcoming extends Component {
state = {
upcomingMovies: []
}
fetchUpcoming() {
fetch(`https://api.themoviedb.org/3/movie/upcoming?api_key=${API_KEY}&language=en-US&page=1`)
// We get the API response and receive data in JSON format...
.then(response => response.json())
// ...then we update upcomingMovies State
.then(data =>
this.setState({
upcomingMovies: data.results
})
)
}
componentDidMount(){
this.fetchUpcoming();
}
render() {
return(
<Container>
{ this.state.upcomingMovies.map((upcomingMovie) => {
console.log(upcomingMovie);
const title = upcomingMovie.title;
console.log(title);
<h1>{title}</h1>
})}
</Container>
)
}
}
Map function should return something to generate ui.
export default class Upcoming extends Component {
state = {
upcomingMovies: []
}
fetchUpcoming() {
fetch(`https://api.themoviedb.org/3/movie/upcoming?api_key=${API_KEY}&language=en-US&page=1`)
// We get the API response and receive data in JSON format...
.then(response => response.json())
// ...then we update upcomingMovies State
.then(data =>
this.setState({
upcomingMovies: data.results
})
)
}
componentDidMount(){
this.fetchUpcoming();
}
render() {
return(
<Container>
{ this.state.upcomingMovies.map((upcomingMovie) => (
<h1>{upcomingMovie.title}</h1>
))}
</Container>
)
}
}
You're missing a return statement in the last line of your map function. It should be return <h1>{title}</h1>
You should write fetchUpcoming by using arrow function. So, you can use this.setState() method on scope of fetchUpcoming function. EX:
const fetchUpcoming = async() {
try {
let response = await fetch(
`https://api.themoviedb.org/3/movie/upcoming?api_key=${API_KEY}&language=en-US&page=1`,
);
let responseJson = await response.json();
return this.setState({
upcomingMovies: responseJson.data.results
})
} catch (error) {
console.error(error);
}
}

React doesn't render data coming from an api response

I've seen a lot of questions and I couldn't get the solution
here is my code:
import React, { Component } from "react";
import axios from "axios";
import "./tree.css";
import "./mainTree";
class TablesTree extends Component {
constructor(props) {
super(props);
this.data = this.props.info;
this.state = {
fields: [],
data: [],
show: false
};
}
componentDidMount() {
var dataGet = [];
this.props.tables.forEach((name, i) => {
this.getFieldsTable(name.TABLE_NAME, (err, res) => {
if (res) {
dataGet.push({
TABLE_NAME: name.TABLE_NAME,
columns: res
});
}
});
});
this.setState({ data: dataGet });
}
getFieldsTable(table, callback) {
axios
.get(`table/columns?name=${this.data.user}&psw=${this.data.password}&schema=${this.data.schema}&table=${table}`)
.then(response => {
callback(null, response.data);
})
.catch(error => {
console.log(error);
});
}
render() {
return (
<div>
{this.state.data
? this.state.data.map((itm, i) => {
return (
<div>
<h1>{itm.TABLE_NAME}</h1>
</div>
);
})
: null}
</div>
);
}
}
export default TablesTree;
I've made console.log of the this.state.data
and the data is in there, but it doesn't renders anything
I've tried a lot of soutions, but I still without rendering the data, I will apreciate your help.
There's a few things I would change about your code, but most importantly you need to do this.setState after your push to dataGet (inside of your callback function).
Because your API call is asynchronous, you are only calling setState once when your component is initially mounted (and while dataGet is still empty).
getFieldsTable is asynchronous, so the dataGet array will be empty when you call setState.
You could return the promise from getFieldsTable and use Promise.all on all the promises, and use the data when all of them have resolved.
Example
class TablesTree extends Component {
// ...
componentDidMount() {
const promises = this.props.tables.map(name => {
return this.getFieldsTable(name.TABLE_NAME).then(res => {
return {
TABLE_NAME: name.TABLE_NAME,
columns: res
};
});
});
Promise.all(promises).then(data => {
this.setState({ data });
});
}
getFieldsTable(table) {
return axios
.get(`table/columns?name=${this.data.user}&psw=${this.data.password}&schema=${this.data.schema}&table=${table}`)
.then(response => {
return response.data;
})
.catch(error => {
console.log(error);
});
}
// ...
}

TypeError: this.state.patients.map is not a function

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!!

Resources