Skip to content

Commit

Permalink
ADD : infinte scroll
Browse files Browse the repository at this point in the history
  • Loading branch information
prayag1740 committed Oct 18, 2022
1 parent f0b89b4 commit b0ebfd7
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 112 deletions.
33 changes: 33 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-infinite-scroll-component": "^6.1.0",
"react-router-dom": "^6.4.2",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
Expand Down
11 changes: 11 additions & 0 deletions public/notes
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
The series of events that happen from mounting of a React component to its unmounting

1) Mounting -- birth of your component.
2) Update -- Growth of component.
3) Unmount -- death of component.


ComponentDidMount -- runs after render method is called
ComponentDidUpdate -- whenever component is updated
ComponentWillUnmount -- called just before component is unmounted and destroyed

1 change: 1 addition & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default class App extends Component {
<Router>
<NavBar />
<Routes>
<Route exact path='/' element={<News key="general" pageSize={this.pageSize} country={'in'} category={'general'} />}></Route>
<Route exact path='/home' element={<News key="general" pageSize={this.pageSize} country={'in'} category={'general'} />}></Route>
<Route exact path='/business' element={<News key="business" pageSize={this.pageSize} country={'in'} category={'business'} />}></Route>
<Route exact path='/entertainment' element={<News key="entertainment" pageSize={this.pageSize} country={'in'} category={'entertainment'} />}></Route>
Expand Down
250 changes: 140 additions & 110 deletions src/components/News.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,128 +2,158 @@ import React, { Component } from "react";
import NewsItem from "./NewsItem";
import Spinner from "./Spinner";
import PropTypes from "prop-types";
import InfiniteScroll from "react-infinite-scroll-component";

export class News extends Component {
static defaultProps = {
country: "in",
pageSize: 8,
category: "science",
};

static propTypes = {
country: PropTypes.string,
pageSize: PropTypes.number,
category: PropTypes.string,
};
export class News extends Component {
static defaultProps = {
country: "in",
pageSize: 8,
category: "science",
};

constructor() {
super();
this.state = {
articles: [],
loading: false,
page: 1,
total_results: 0,
static propTypes = {
country: PropTypes.string,
pageSize: PropTypes.number,
category: PropTypes.string,
};
}

//Lifecycle method run after render method is called ; used for loading of data
componentDidMount() {
this.fetchNewsData(this.state.page); //intially fetch data for 1st page
}
constructor(props) {
super(props);
this.state = {
articles: [],
loading: true,
page: 1,
total_results: 0,
};
document.title = `${this.capitalizestr(this.props.category)} -- Newsmonkey`;
}

capitalizestr(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}

handleNextClick = () => {
this.setState({ page: this.state.page + 1 });
console.log(this.state.page);
this.fetchNewsData(this.state.page + 1);
};
//Lifecycle method run after render method is called ; used for loading of data
componentDidMount() {
this.fetchNewsData(this.state.page); //intially fetch data for 1st page
}

handleNextClick = () => {
this.setState({ page: this.state.page + 1 });
console.log(this.state.page);
this.fetchNewsData(this.state.page + 1);
};

handlePrevClick = () => {
this.setState({ page: this.state.page - 1 });
console.log(this.state.page);
this.fetchNewsData(this.state.page - 1);
};

handlePrevClick = () => {
this.setState({ page: this.state.page - 1 });
console.log(this.state.page);
this.fetchNewsData(this.state.page - 1);
};
async fetchNewsData(page) {
let todayDate = this.getCurrentDate();
const url =
`https://newsapi.org/v2/top-headlines?country=${this.props.country}&category=${this.props.category}&from=${todayDate}&sortBy=publishedAt&apiKey=7d248d9c8ea64fa6a4691432a30a74ac&pageSize=${this.props.pageSize}&page=` +
page;
console.log(url);
this.setState({ loading: true });
let data = await fetch(url);
let parsedData = await data.json();
console.log(parsedData);
this.setState({ loading: false });
this.setState({
articles: parsedData.articles,
total_results: parsedData.totalResults,
});
}

async fetchNewsData(page) {
let todayDate = this.getCurrentDate();
const url =
`https://newsapi.org/v2/top-headlines?country=${this.props.country}&category=${this.props.category}&from=${todayDate}&sortBy=publishedAt&apiKey=7d248d9c8ea64fa6a4691432a30a74ac&pageSize=${this.props.pageSize}&page=` +
page;
console.log(url);
this.setState({ loading: true });
let data = await fetch(url);
let parsedData = await data.json();
console.log(parsedData);
this.setState({ loading: false });
this.setState({
articles: parsedData.articles,
total_results: parsedData.totalResults,
});
}
showNextButton() {
return (
this.state.page + 1 >
Math.ceil(this.state.total_results / this.props.pageSize)
);
}

showNextButton() {
return (
this.state.page + 1 >
Math.ceil(this.state.total_results / this.props.pageSize)
);
}
fetchMoreData = async() => {
this.setState({page : this.state.page + 1});
let todayDate = this.getCurrentDate();
let newPage = this.state.page + 1
const url =
`https://newsapi.org/v2/top-headlines?country=${this.props.country}&category=${this.props.category}&from=${todayDate}&sortBy=publishedAt&apiKey=7d248d9c8ea64fa6a4691432a30a74ac&pageSize=${this.props.pageSize}&page=` +
newPage;
console.log(url);
let data = await fetch(url);
let parsedData = await data.json();
console.log(parsedData);
this.setState({ loading: false });
this.setState({
articles: this.state.articles.concat(parsedData.articles),
total_results: parsedData.totalResults,
});
} ;

getCurrentDate() {
var today = new Date();
var dd = String(today.getDate()).padStart(2, "0");
var mm = String(today.getMonth() + 1).padStart(2, "0"); //January is 0!
var yyyy = today.getFullYear();
getCurrentDate() {
var today = new Date();
var dd = String(today.getDate()).padStart(2, "0");
var mm = String(today.getMonth() + 1).padStart(2, "0"); //January is 0!
var yyyy = today.getFullYear();

today = yyyy + "-" + mm + "-" + dd;
return today;
}
today = yyyy + "-" + mm + "-" + dd;
return today;
}

render() {
return (
<div className="container my-3">
{this.state.loading && <Spinner />}
<h1 className="text-center" style={{ margin: "35px 0px" }}>
{" "}
NewsMonkey -- Top Headlines
</h1>
<div className="row">
{!this.state.loading &&
this.state.articles.map((element) => {
return (
<div className="col md-4" key={element.url}>
<NewsItem
title={element.title.slice(0, 45)}
description={element.description}
imageUrl={element.urlToImage}
newsUrl={element.url}
author={element.author}
date={element.publishedAt.slice(0, 10)}
/>
</div>
);
})}
</div>
<div className="container d-flex justify-content-between">
<button
disabled={this.state.page <= 1}
type="button"
className="btn btn-dark"
onClick={this.handlePrevClick}
>
{" "}
&larr; Previous
</button>
<button
disabled={this.showNextButton()}
type="button"
className="btn btn-dark"
onClick={this.handleNextClick}
>
Next &rarr;{" "}
</button>
</div>
</div>
);
}
render() {
return (
<div className="container my-3">
<h1 className="text-center" style={{ margin: "35px 0px" }}>
{" "}
NewsMonkey -- Top {this.capitalizestr(this.props.category)} Headlines
</h1>
{this.state.loading && <Spinner />}
<InfiniteScroll
dataLength={this.state.articles.length}
next={this.fetchMoreData}
hasMore={this.state.articles.length !== this.state.total_results}
loader={<Spinner />}>
<div className="row">
{this.state.articles.map((element) => {
return (
<div className="col md-4" key={element.url}>
<NewsItem
title={element.title.slice(0, 45)}
description={element.description}
imageUrl={element.urlToImage}
newsUrl={element.url}
author={element.author}
date={element.publishedAt.slice(0, 10)}
/>
</div>
);
})}
</div>
</InfiniteScroll>
{/* <div className="container d-flex justify-content-between">
<button
disabled={this.state.page <= 1}
type="button"
className="btn btn-dark"
onClick={this.handlePrevClick}
>
{" "}
&larr; Previous
</button>
<button
disabled={this.showNextButton()}
type="button"
className="btn btn-dark"
onClick={this.handleNextClick}
>
Next &rarr;{" "}
</button>
</div> */}
</div>
);
}
}

export default News;
2 changes: 1 addition & 1 deletion src/components/NewsItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class NewsItem extends Component {
<h5 className="card-title">{title}</h5>
<p className="card-text">{description}</p>
<a href={newsUrl} rel="noreferrer" target='_blank' className="btn btn-sm btn-primary">Read More</a>
<p className="card-text mt-2"><small class="text-muted">By {author? author : 'Unknown'} on {date}</small></p>
<p className="card-text mt-2"><small className="text-muted">By {author? author : 'Unknown'} on {date}</small></p>
</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Spinner.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import loading from './loading.gif'
export default function Spinner() {
return (
<div className='text-center'>
<img src={loading} alt="Loading" />
<img className='my-3' src={loading} alt="Loading" />
</div>
)
}

0 comments on commit b0ebfd7

Please sign in to comment.