React HOC with Router not finding page - reactjs

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 }));
}

Related

Update state with API Call - React.js

I'm trying to update state in React.js using an API call, as I need to show some of the data to the end user.
The api call works through localhost:5001 and is stored in Firebased functions.
import React, { Component } from 'react'
import './Table.css';
class Table extends Component {
constructor (props)
{
super(props);
this.state = {
stocks: []
};
}
componentDidMount() {
fetch('localhost:5001') // Removed for stackoverflow //
.then((response) => response.json())
.then(stockList => {
this.setState =
({ stocks: stockList });
});
}
render() {
return (
<div className='table'>
<h1 id='title'>Companies</h1>
{this.state.stocks.map(stocks => <h2 key={stocks.symbol}> {stocks.companyName}</h2>)}
</div>
)
}
}
export default Table;
Here is a snippet of the API call:
{"symbol":"AAPL","companyName":"Apple Inc"}
setState is a function, so you should call it, rather that assign values to it:
this.setState({ stocks: stockList });

How to pass props to API URL in React js?

i'm new to React and I need help with passing props to API URL. I have two class components -> (MyClass) works fine. However when I use variable from MyClass as props in other class component (MyOtherClass), it seems to work only in "render" part. I mean <div> variable: {variable}, url : {url2}</div> is shown in app as expected but when I try to pass this variable from props to API URL, it is not working and instead the URL looks like this: "http://localhost:55111/status/[object Object]". Any ideas what might cause the problem??
Here's my code:
import React, { Component } from 'react'
import axios from 'axios'
export default class MyClass extends Component {
constructor(props) {
super(props);
this.state = {
data: {}
}
}
componentDidMount() {
axios
.get("http://localhost:55111/start")
.then(response => {
this.setState({
data: response.data
});
console.log(this.state.data);
})
.catch(err => {
this.err = err;
});
}
render() {
const variable = this.state.data.sent
return (
<div>
<h1>Hello worlds</h1>
<p>var: {variable}</p>
<MyOtherClass variable={variable} />
</div>
);
}
}
This is the other class component causing troubles:
class MyOtherClass extends Component {
constructor(props) {
super(props);
this.state = {
data: {}
};
}
async componentDidMount() {
const {variable} = this.props
axios.get(`http://localhost:55111/status/${variable}`)
.then(response => {
this.setState({
data: response
});
console.log(this.state);
})
render() {
const { variable } = this.props
const url2 = `http://localhost:55111/status/${variable}`
return (
<div>variable: {variable}, url : {url2}</div>
);
}
}
import React, { Component } from 'react'
import axios from 'axios'
export default class MyClass extends Component {
constructor(props) {
super(props);
this.state = {
data: {}
}
}
componentDidMount() {
this.getData()
}
async getData() => {
const response = await axios.get("http://localhost:55111/start")
this.setState({data: response.data})
}
render() {
const variable = this.state.data.sent
return (
<div>
<h1>Hello worlds</h1>
<p>var: {variable}</p>
<MyOtherClass variable={variable} />
</div>
);
}
}
Use the async await.

this.state.data.map is not a function

I'm making an API call with React and the Facebook Graph API
The API is working fine but the map method is showing
this.state.data.map is not a function
import React, { Component } from 'react';
import axios from 'axios';
class user extends Component {
constructor(props){
super(props);
this.state={
data:[123]
}
}
componentDidMount() {
axios.get("facebook url")
.then(response => {
if (response.status === 200 && response != null) {
this.setState({
data: response.data
});
} else {
console.log('problem');
}
})
.catch(error => {
console.log(error);
});
}
render(){
return (
<div>
{this.state.data.map((item,index) => {
return (
<div key={item.id}>
<h1>{item.message}</h1>
</div>
);
})}
</div>
);
}
}
export default user;

Fetch API data using React

I have a react, which uses django rest framework API. I'm to get JSON data but it seems I'm not fetching the information correctly or I'm not rendering in the right way:
import React, { Component } from 'react' ;
class App extends Component {
state = {
todos: []
};
async componentDidMount() {
fetch('http://127.0.0.1:8000/api/todos/')
.then(results =>{
console.log(results)
const get_todos = results.map( c=>{
return {
id: c.id,
title: c.title,
descripttion: c.title
};
});
const newstate = Object.assign({},this.state,{
todos: get_todos
});
this.setState(newstate);
}).catch(error=> console.log(error));
}
render(){
return (
<div className="App">
{this.state.todos}
</div>
)
}
}
export default App;
it should be
state = { loading : true }
componentDidMount() {
fetch('http://127.0.0.1:8000/api/todos/')
.then(blob => blob.json())
.then(response => {
...
})
}

React: Http request response not displaying in render()

Can someone tell me what is wrong with my code below? I am making an HTTP request to Darksky API using 'superagent' and then trying to display the result in an h2 which isn't working. I tried logging it to console and it works perfectly but if I am trying to display it on the page it doesn't work. Could someone help me out pls, I am new to react and not sure what is going wrong.
import React, { Component } from "react";
import "./Body.css";
import Request from "superagent";
class Body extends Component {
constructor() {
super();
this.getData = this.getData.bind(this);
}
getData() {
var url = this.props.apiUrl;
Request.get(url)
.then(response => {
return(JSON.stringify(response.currently.summary));
})
.catch(error => {});
}
render() {
<div>
<h2>
{this.getData()}
</h2>
</div>
}
}
export default Body;
This is the other file where I am importing Body.js :-
import React, { Component } from "react";
import Body from "./Body";
import "./App.css";
class App extends Component {
render() {
return <Body
apiUrl="https://api.darksky.net/forecast/42a9693aecf45c358afbda0022c5cf65/28.5355,77.3910" />;
}
}
export default App;
You need to set your data in the state of the component, it fire new render:
constructor() {
super();
this.getData = this.getData.bind(this);
this.state = {data: {}}
}
componentDidMount() {
var url = this.props.apiUrl;
Request.get(url)
.then(response => this.setState({data: JSON.stringify(response.currently.summary)}))
.catch(error => {});
}
render(){
console.log("your data", this.state.data);
return <div>test</div>;
}
And work with this data with this.state.data.
I advise you to change getData() function to componentDidMount mehtod.
You should use a life cycle method(componentDidMount) with the use of state. It is recommended to make HTTP calls inside the componentDidMount() method.
constructor() {
super();
this.state = {
result: ''
};
}
componentDidMount(){
var url = this.props.apiUrl;
Request.get(url)
.then(response => {
this.setState({
result: JSON.stringify(response.currently.summary)
});
})
.catch(error => {});
}
render() {
<div>
<h2>
{this.state.result}
</h2>
</div>
}

Resources