New to React Native here... I'm trying to call a function that does a get request inside a component which is in the render() method.
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
export default class Home extends React.Component {
static navigationOptions = {
title: 'Details',
};
getMoviesFromApiAsync = () => {
return fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
return responseJson.movies;
})
.catch((error) => {
console.error(error);
});
};
render() {
return (
<React.Fragment>
<Text>{getMoviesFromApiAsync()}</Text>
</React.Fragment>
);
}
}
However, I'm getting ReferenceError: Can't find variable getMoviesFromApiAsync(). Why is this?
Error Image
You need to call the method on your class, this is a basic Vanilla Javascript thing.
<Text>{this.getMoviesFromApiAsync()}</Text>
However, your approach here is not good, you should write the component out to store the results from your api request in component state. this way you dont need to make a request every render cycle!
export default class Home extends React.Component {
static navigationOptions = {
title: 'Details',
};
state = {
movies: []
}
componentDidMount() {
this.getMoviesFromApiAsync()
}
getMoviesFromApiAsync = () => {
return fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
movies: [...this.state.movies, ...responseJson.movies]
})
})
.catch((error) => {
console.error(error);
});
};
render() {
const { movies } = this.state
return (
<React.Fragment>
{ movies.map( (movie, i) => <Text>{movie.title}</Text> ) }
</React.Fragment>
);
}
}
Related
Hi I am working on a react app with Routing and HOC. I expect to see a page but i get page not found when i know the page is there.
in componentDidMount this.setState, data is shown as undefined but in the HOC wrapper i see the data arrive from the server.
Before I wrapped the page in HOC i could see it rendering content so I know the content exists.
Here is my Page component which is being called via a Route :
import React, { Component } from "react";
import WithBackend from "./WithBackend";
class Page extends Component {
constructor(props) {
super(props);
this.state = { model: null };
}
render() {
if (this.state.model != null) {
return (
<div className="container">
<div className="row">
<div className="col-md">
<h1>{this.state.model.title}</h1>
</div>
</div>
</div>
);
} else {
return (
<div>
<h2>Home</h2>
</div>
);
}
}
componentDidMount() {
const data = this.props.getPage("1");
console.log(data);
this.setState({
model: data,
});
}
}
export default WithBackend(Page);
Here is the HOC component WithBackend: I am not sure if i should be setting the state on this class on in the class that is being wrapped.
When i debug the code in the getPage method, in the setState part i see the data being populated from the backend server.
import React from "react";
import ContentService from "./ContentService";
const WithBackend = (WrappedComponent) => {
class HOC extends React.Component {
constructor() {
super();
this.contentService = new ContentService();
this.getPage = this.getPage.bind(this); // <-- Add this
}
getPage(id) {
this.contentService
.getPage(id)
.then((response) => response.json())
.then((data) => {
this.setState({ model: data });
})
.catch((e) => {
console.log(e);
});
}
render() {
return <WrappedComponent getPage={this.getPage} {...this.props} />;
}
}
return HOC;
};
export default WithBackend;
and here is the contentService which only returns a promise:
class ContentService {
pageUrl = process.env.REACT_APP_BASE_URL + "/pages/";
getPage(id) {
const path = this.pageUrl + id;
const fetchPromise = fetch(path, {
method: "GET",
});
return Promise.resolve(fetchPromise);
}
}
export default ContentService;
Could anyone please advice what i am doing wrong?
Thanks in advance.
getPage is an asynchronous method, that should return a promise:
getPage(id) {
return this.contentService
.getPage(id)
.then((response) => response.json())
.catch((e) => {
console.log(e);
});
}
And then
componentDidMount() {
this.props.getPage("1").then(model => this.setState({ model }));
}
I need help to display the data from the API.
When i try to get the data with map i get an error. TypeError: userdata.map is not a function
import React from "react";
import axios from "axios";
export class HighscoreList extends React.Component {
constructor(props) {
super(props);
this.state = {
users: ""
};
}
componentDidMount() {
axios
.get("https://schnitzeljagdar.herokuapp.com/users/getAllUser")
.then(response => {
console.log(response.data);
})
.catch(error => {
console.log(error);
});
}
render() {
return (
<React.Fragment>
<h2>User</h2>
{this.state.users}
</React.Fragment>
);
}
}
Try this https://codesandbox.io/s/wonderful-cherry-63ee9
export default class HighscoreList extends React.Component {
state = {
users: []
};
componentDidMount() {
axios
.get("https://schnitzeljagdar.herokuapp.com/users/getAllUser")
.then(res => this.setState({users:[res.data]}))
.catch(error => {
console.log(error);
});
}
render() {
const {users} = this.state;
let array = users[0]?Object.values(users[0]):[];
console.log(array)
return (
<React.Fragment>
{array.map((arr,index)=>
<div key={index}>
<h2>{arr.username}</h2>
<p>{arr.email}</p>
</div>
)}
</React.Fragment>
);
}
}
how to display html elements in react java script window through scripting. I have tried using json data but the elements are hard coded in html.
suggest me how to approach.
class App extends Component {
constructor() {
super();
this.state = {
data: '',
}
}
componentDidMount() {
fetch('http')
.then((response) => response.json())
.then((response) => {
// fetch the text
fetch(response.url)
.then(response2 => response2.text())
.then(response2 => {
this.setState({
data: response2
})
})
})
}
render() {
return (
<div>
{this.state.data}
</div>
)
}
}
export default App;
I am using nested route. Parent component shows category list and the child component shows modal. On performing delete action in modal i.e. child, I am redirecting to the parent route using history.push. The component is getting rendered but without re-rendering the component i.e. the record which was deleted still appears in the view, but when I refresh the page the record does not appear. Any suggestions on this?
Here is my code -
CategoryList.js
import React, { Component } from 'react';
import { Route, Link } from 'react-router-dom';
import CustomisedModal from './../../elements/CustomisedModal';
class CategoryList extends Component {
state = {
categories: [],
}
componentDidMount() {
fetch('http://localhost:8080/xxxx')
.then(results => {
return results.json();
}).then(data => {
this.setState({ categories: data.categories });
})
.catch(error => {
this.setState({ error: true });
});
}
deleteCategoryHandler = (id) => {
**//navigate to modal**
this.props.history.replace('/category/delete/' + id);
}
render() {
if (!this.state.error) {
categories = this.state.categories.map(category => {
return (
xxxxx
)
})
}
return (
<Container>
xxxx
<Route path="/category/delete/:id" exact component={DeleteCategory} /> **<!--Nested route-->**
</Container>
);
}
}
export default CategoryList;
CustomisedModal.js
import React from 'react'
import { Button, Header, Modal, Icon } from 'semantic-ui-react';
class CustomisedModal extends React.Component {
constructor(props) {
super(props);
this.state = {
showModal: this.props.props
}
}
onClose = () => {
this.props.props.history.go('/category');
}
deleteCategory = () => {
fetch('http://localhost:8080/xxxx/' + this.props.props.match.params.id , {
method: 'delete'
})
.then(results => {
return results.json();
}).then(data => {
**//Redirect to parent route**
this.props.props.history.go('/category');
})
.catch(error => {
this.setState({ error: true });
});
}
render() {
return (
<Modal> xxxx
</Modal>
)
}
}
export default CustomisedModal;
the problem here is your parent component has the fetch call in componentDidMount. use componentWillReceiveProps with some condition to reload the data after delete action. As the current parent state hold the old data.
Hope this will help
Fixed the issue by updating state on receiving response so that component gets re-rendered
CustomisedModal.js
import React from 'react'
import { Button, Header, Modal, Icon } from 'semantic-ui-react';
class CustomisedModal extends React.Component {
constructor(props) {
super(props);
this.state = {
categories: this.props.props.categories **added categories to state**
}
}
onClose = () => {
this.props.props.history.go('/category');
}
removeByAttr = function (arr, attr, value) {
var i = arr.length;
while (i--) {
if (arr[i]
&& arr[i].hasOwnProperty(attr)
&& (arguments.length > 2 && arr[i][attr] === value)) {
arr.splice(i, 1);
}
}
return arr;
}
deleteCategory = () => {
fetch('http://localhost:8080/xxxx/' + this.props.props.match.params.id , {
method: 'delete'
})
.then(results => {
return results.json();
}).then(data => {
**//Redirect to parent route**
let newArray = this.removeByAttr(this.state.categories, 'id', data.id);
this.setState({ categories: newArray }); **//updated setState**
this.props.props.history.go('/category');
})
.catch(error => {
this.setState({ error: true });
});
}
render() {
return (
<Modal> xxxx
</Modal>
)
}
}
export default withRouter(CustomisedModal);**// added withRouter**
So, I can't figure out why the last line in my code ends up displaying an error, and I couldn't find any other posts that help in my particular case. Here's the code:
import React, { Component } from 'react';
import { View, Text } from 'react-native';
class AlbumList extends Component {
state = { albums: [] };
componentWilMount() {
fetch('https://rallycoding.herokuapp.com/api/music_albums')
.then(response => response.json())
.then(response => this.setState({ albums: response.data }));
}
renderAlbums() {
return this.state.albums.map(album => <Text>{album.title}</Text>);
}
render() {
console.log(this.state.albums);
}
return() {
<View>
{this.renderAlbums()}
</View>
}
Because you call return like method, but return should be in your render() method.
import React, { Component } from 'react';
import { View, Text } from 'react-native';
class AlbumList extends Component {
state = { albums: [] };
componentWilMount() {
fetch('https://rallycoding.herokuapp.com/api/music_albums')
.then(response => response.json())
.then(response => this.setState({ albums: response.data }));
}
renderAlbums() {
return this.state.albums.map(album => <Text>{album.title}</Text>);
}
render() {
console.log(this.state.albums);
return (
<View>
{this.renderAlbums()}
</View>
);
}
}