How to map through a responses from an API in react - reactjs

I did fetch data from the NYTimes API and console log the response in the browser. I have done this by writing a function do_search. How can I send the responses as a prop to another component?
Here is a response form the API.
Here is my code for INDEX.JS. Please notice that I want to pass the prop in Listview component which is at 6th line from the last.
import React from "react";
import ReactDOM from "react-dom";
import SearchComponent from "./components/Search_component";
import ListViewComponent from "./components/Listview_component";
import _ from "lodash";
const axios = require("axios");
const api_key = "my_api_key";
let url = "https://api.nytimes.com/svc/search/v2/articlesearch.json";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
q: " "
};
this.do_search("Bangladesh");
this.do_search = this.do_search.bind(this);
}
do_search(keyword) {
axios
.get(
url, // takes the variable url
{
params: {
api_key: api_key,
q: keyword
}
}
)
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
}
render() {
const search_throttle = _.debounce(keyword => {
this.do_search(keyword);
}, 500);
return (
<div>
<SearchComponent
searchkeyword={
search_throttle
}
/>
<ListViewComponent data={this.do_search.response.docs} />
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));

Assign the response to a state and pass this state as a prop.
this.state = {
q: " ",
searchResponse :null,
};
........
do_search = (keyword) =>{
axios
.get(...)
.then(function(response) {
console.log(response);
this.setState({searchResponse:response.data});
})
.........
<ListViewComponent data={this.state.searchResponse} />
</div>
Now when ever the state value gets its response from api, render is called again and listview gets the value.

Make an array where you will push response.data from then method in axios. Pass that array as prop to ListView component.
Inside ListView component make some loader that will show to the user that component is fetching data. When data arrives, show what you got from NYTimes API

Notice that when your state changes, views are re-rendered with props updated
import React from "react";
import ReactDOM from "react-dom";
import SearchComponent from "./components/Search_component";
import ListViewComponent from "./components/Listview_component";
import _ from "lodash";
const axios = require("axios");
const api_key = "9f4cd2e5a8884f3eb5853436e74be7e6";
let url = "https://api.nytimes.com/svc/search/v2/articlesearch.json";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
q: " "
};
this.do_search("Bangladesh");
this.do_search = this.do_search.bind(this);
}
do_search(keyword) {
axios
.get(
url, // takes the variable url
{
params: {
api_key: api_key,
q: keyword
}
}
)
.then(function(response) {
console.log(response);
this.setState({ response }); // SET STATE HERE
})
.catch(function(error) {
console.log(error);
});
}
render() {
const search_throttle = _.debounce(keyword => {
this.do_search(keyword);
}, 500);
return (
<div>
<SearchComponent
searchkeyword={
search_throttle
}
/>
<ListViewComponent data={this.state.response} /> // GET STATE HERE
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));

Related

react handler array from axios

How I handle the value array from Axios and fill the card
get the value from the array and show data
import React, { Component, Suspense } from "react";
import axios from "axios";
import {Card} from "reactstrap";
import { PHP } from "../../constants";
//api url adress server
const api = PHP;
const reqtoken = "Bearer " + localStorage.getItem("token");
class Property extends Component {
constructor(props) {
super(props);
this.state = {
data: []
};
}
load() {
axios
.get(api + "api/property", {
headers: {
"Content-type": "application/json",
Authorization: reqtoken
}
})
insert the data array on the state
.then(json => {
console.log show the data on console terminal
console.log(json.data.data.data);
this.setState({
data: json.data.data.data
});
})
.catch(erros => {
console.log(erros);
});
}
componentDidMount() {
this.load();
}
render() {
return (
<div>
map the array to handle the result................
{this.state.data.map(i => (
<Card>
<li>{i.address}</li>
</Card>
))}
</div>
);
}
}
export default Property;
didn't make me a wrong error console
I don't know how the response data comes in, but I found a problem with the code. You should pass keys.
{this.state.data.map(item => (
<Card key={item.id}>
<li>{item.address}</li>
</Card>
))}
https://reactjs.org/docs/lists-and-keys.html#keys

React - Call javascript function after ajax returned data has been rendered

I have the following data loader component in react. It fetches data from API endpoint and renders HTML with that data.
import React, { Component } from "react";
import PropTypes from "prop-types";
class DataLoader extends Component {
static propTypes = {
endpoint: PropTypes.string.isRequired,
render: PropTypes.func.isRequired,
callback: PropTypes.func
};
state = {
data: [],
loaded: false,
placeholder: "Loading..."
};
componentDidMount()
{
fetch(this.props.endpoint)
.then(response => {
if (response.status !== 200) {
return this.setState({ placeholder: "error" });
}
return response.json();
})
.then(data => this.setState({ data: data, loaded: true } ))
.then( this.props.callback );
}
render() {
const { data, loaded, placeholder } = this.state;
return loaded ? this.props.render(data) : <p>{placeholder}</p>;
}
}
export default DataLoader;
Here is App.jsx file
import React from "react";
import ReactDOM from "react-dom";
import DataLoader from "./DataLoader";
import EventDivs from "./EventDivs";
const App = () => (
<DataLoader endpoint="api/v1/calendarevents/"
render={data => <EventDivs data={data} />}
callback = {function() {
console.log($("#renderedDiv").length);
}}
/>
);
const appid = document.getElementById("app");
appid ? ReactDOM.render(<App />, appid ) : null;
console.log($("#renderedDiv").length) gets 0, because this.props.callback is callback of fetch.
I want to know how to call the function after the data that Ajax returned has been rendered?

componentDidMount not firing in React

import React from 'react';
import ReactDOM from 'react-dom';
import $ from 'jquery';
import Post from './components/Post.jsx';
import Feed from './components/Feed.jsx';
class App extends React.Component {
constructor() {
super();
this.state = {
view: 'feed',
collection: ''
}
}
componentDidMount() {
console.log('component did mount')
this.getCollection();
}
async getCollection() {
try {
const response = await fetch('/api/page');
const responseJSON = await response.json();
this.setState({ collection: responseJSON }, () => {
console.log("App Component - getCollection() State Updated", this.state);
});
} catch (error) {
console.log("App Component - getCollection() error", error);
}
}
render() {
return (
<div>
Text
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'));
Can't get component did mount to function. Trying to make an ajax request to my mongodb and render that on the client side. All I need to do now is make a state change setting the collection to the information I get back. I tried using an Ajax request but that didnt work. Now I'm implementing an async fetch call as per the suggestion of another contributor.
the nonworking ajax request:
As of now, componentDidMount is still not being triggered and the collection property of the state is still an empty string.
I would recommend using the Fetch API for AJAX calls and making use of ES6 Async/Await, since importing an entire library just for Ajax seems a bit overkill.
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
collection: ''
}
this.getCollection = this.getCollection.bind(this)
}
componentDidMount() {
console.log('component did mount')
this.getCollection();
}
async getCollection() {
try {
const response = await fetch('/api/blogs');
const responseJSON = await response.json();
this.setState({ collection: responseJSON }, () => {
console.log("App Component - getCollection() State Updated", this.state);
});
} catch (error) {
console.log("App Component - getCollection() error", error);
}
}
render() {
return (
<div>
<h1>Welcome</h1>
</div>
);
}
}
ReactDOM.render(<App /> , document.getElementById('app'));
I'm not sure what you're doing with your render, but I've left it out. Hopefully, this will shed some light on how best to perform what you want.
To get componentDidMount to fire you need the render function. Because first the component renders and then it calls the function componentDidMount.
I think adding this to your class should solve your problem.
render() {
return null;
}

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

Axios data being returned, but calling code not working

Thanks in advance for reading. I am realtively new to the react and es6 world. I had a working component that used axios to call an api. All good. Re-engineered it to put redundant api call code into a utils and call it from anywhere that needs data. But I cannot figure out why this function call isn't working. Anyone see what I am missing?
Here is the utility function:
import Axios from 'axios';
export function getData(strPath){
var sendToken = {
headers: {'Authorization': 'Token tokenHere'}
};
var sendPath = "http://pathHere.com/api/" + strPath
Axios
.get(sendPath,sendToken)
.catch(function (error) {
//error handling here
})
.then(function (response) {
console.log(response.data.results) //outputs my array of 2 elements
return(response.data.results);
})
};
Here is the calling react component:
import React, { Component } from 'react';
import { getData } from './Utils';
class BoardContainer extends React.Component {
constructor(props){
super(props);
this.state = { positions: [] };
}
componentWillMount(){
var x = getData('positions'); //simplified code for debugging and example
console.log(x); //ISSUE: x is undefined
}
render() {
return(
<div>Testing Rendering Board Container
//rendering code would be here (child component call)
</div>
)
}
}
Utility:
import Axios from 'axios'
export function getData(strPath){
const sendToken = {
headers: {'Authorization': 'Token tokenHere'}
}
const sendPath = "http://pathHere.com/api/" + strPath
return Axios.get(sendPath, sendToken)
};
Component:
import React, { Component } from 'react'
import { getData } from './Utils'
class BoardContainer extends React.Component {
constructor(props){
super(props);
this.state = { positions: [] }
}
componentWillMount(){
getData('positions').then((response) => {
console.log(response)
}).catch((error) => {
console.log(error)
})
}
render() {
return(
<div>Testing Rendering Board Container
//rendering code would be here (child component call)
</div>
)
}
}

Resources