Pagination with json-server and React.js - javascript

I am trying to paginate JSON data that I am using with JSON server in React. I am currently using splice to break the data up into pages with 10 items per page. To get the data from each splice I have an unordered list where the list items are assigned the data. I actually want to just have pages and a next button rather than have each page listed at the top of the page, but I cant seem to wrap my head around it. I would like to use _page _limit. Any help would be appreciated. Here is the code.
import React, { Component } from 'react';
// added axios to assist with API calls.
import axios from 'axios';
import './App.css';
import Card from './Card.js';
import SearchBar from "./SearchBar.js"
import star from './images/star.svg';
import wars from './images/wars.svg';
class App extends Component {
constructor(props) {
super(props);
this.state = {
people: []
}
}
componentDidMount() {
this.getPeopleData();
}
getPeopleData(search) {
axios.get('http://localhost:3008/people?_start=0&_end=9&q=' + search).then((response) => {
this.setState ({
people: response.data
});
});
}
//1. Using axios and decided to use the slice method rather than the _page _limit from https://github.com/typicode/json-server#slice
limitPerPage (begin, end) {
axios(`http://localhost:3008/people?_start=${begin}&_end=${end}`).then((response) => {
this.setState ({
people: response.data
});
});
}
render() {
return (
<div className='content'>
<div className='logo'>
<img src={star} alt="star-logo" />
<span className='interview-text'>The Interview</span>
<img src={wars} alt="wars-logo" />
</div>
<h2>Cards</h2>
{/* Decided to display the card pages as a list. Each page holds 10 cards */}
<ul className="card-pagination">
<li>
<a onClick={() => this.limitPerPage(0, 9)}>Page 1</a>
</li>
<li>
<a onClick={() => this.limitPerPage(10, 19)}>Page 2</a>
</li>
<li>
<a onClick={() => this.limitPerPage(20, 29)}>Page 3</a>
</li>
<li>
<a onClick={() => this.limitPerPage(30, 39)}>Page 4</a>
</li>
<li>
<a onClick={() => this.limitPerPage(40, 49)}>Page 5</a>
</li>
<li>
<a onClick={() => this.limitPerPage(50, 59)}>Page 6</a>
</li>
<li>
<a onClick={() => this.limitPerPage(60, 69)}>Page 7</a>
</li>
<li>
<a onClick={() => this.limitPerPage(70, 79)}>Page 8</a>
</li>
<li>
<a onClick={() => this.limitPerPage(80, 89)}>Page 9</a>
</li>
</ul>
{this.state.people.map((person) => {
return <Card
key={person.id}
id={person.id}
name={person.name}
imageURL={('http://localhost:3008/' + person.image)}
birthday={person.birth_year}
planetList={this.state.planets}
homeWorld={person.homeworld}
/>
})}
</div>
);
}
}
export default App;

constructor(props) {
super(props);
this.state = {
people: [],
_page_limit: 10,
currentPage: 0
}
}
...
limitPerPage (begin, end, increase) {
axios(`http://localhost:3008/people?_start=${begin}&_end=${end}`).then((response) => {
this.setState ({
people: response.data,
currentPage: this.state.currentPage + increase
});
});
}
_renderLinks() {
var cp = this.state.currentPage
if (cp == 0) {
// show only "Page 1" and "Next"
return (
<ul className="card-pagination">
<li>Page 1</li>
<li><a onClick={() => this.limitPerPage(10, 20, 1)}>Next</a></li>
</ul>
)
} else if (cp < this.state._page_limit - 1) {
// show "Back", "Page X" and "Next"
return (
<ul className="card-pagination">
<li><a onClick={() => this.limitPerPage((cp-1) * 10, cp * 10), -1}>Back</a></li>
<li>Page {(cp + 1}</li>
<li><a onClick={() => this.limitPerPage((cp+1) * 10, (cp+2) * 10, 1}>Next</a></li>
</ul>
)
} else {
// show "Back", "Page X" and "Next"
return (
<ul className="card-pagination">
<li><a onClick={() => this.limitPerPage((cp-1) * 10, cp * 10, -1)}>Back</a></li>
<li>Page {(cp-1)}</li>
</ul>
)
}
}
render() {
var _page_limit = 10
return (
<div className='content'>
<div className='logo'>
<img src={star} alt="star-logo" />
<span className='interview-text'>The Interview</span>
<img src={wars} alt="wars-logo" />
</div>
<h2>Cards</h2>
{this._renderLinks()}
{this.state.people.map((person) => {
return <Card
key={person.id}
id={person.id}
name={person.name}
imageURL={('http://localhost:3008/' + person.image)}
birthday={person.birth_year}
planetList={this.state.planets}
homeWorld={person.homeworld}
/>
})}
</div>
);
}
}
The expression [...Array(_page_limit).keys()] is a shortcut for creating an array of numbers between 0 and (_page_limit - 1), inclusive.

Related

How to get last data and set a color in map foreach in reactjs

const pages = ["main", "about", "contact"];
const pagesList = pages.map((page) => <li>{page}</li>);
Result:
<ul>
<li>Main</li>
<li>About</li>
<li>Contact</li>
</ul>
i want to set "a" tag to "Main and About" "li". How can i do that? Thanks for your help
If you want to use map, you can try this
const pages = ["main", "about", "contact"];
let currentIndex = 0;
const pagesList = pages.map((page) =>
{
currentIndex === pages.length - 1 ? <li>{page}</li> : <li a>{page}</li>
currentIndex++;
});
Thanks to everyone who helped me. I solved my problem
i was trying to this:
<ul>
<li>
<a href='/test'>Home</a>
</li>
<li>
<a href='/test'>test1</a>
</li>
<li>
<a href='/test'>test2</a>
</li>
<li>
<a href='/test'>test3</a>
</li>
<li>test4</li>
</ul>
every li elements has "a" element but last li not have "a" element i tried to do this.
my pageHeader.js component its like this
import React from "react";
import { Link } from "react-router-dom";
export const PageHeader = (props) => {
const pages = props.pages;
const pagesList = pages.map((page) => (
<>
{page == pages[pages.length - 1] ? (
<li>{page}</li>
) : (
<li>
<Link to='test'>{page}</Link>
</li>
)}
</>
));
return (
<>
<div className='pageHeader'>
<ul>{pagesList}</ul>
</div>
</>
);
};
I find the last data with javascript length expression;
I added element "a" with "if" "else" statements.
then i called this component in my work place like this:
<PageHeader pages={["Home", "test1", "test2", "test3", "test4"]} />
you can solve this by CSS only
ul.parent>*:last-child {
color: red;
}
<ul class="parent">
<li>Main</li>
<li>About</li>
<li>Contact</li>
</ul>

How can i pass a return value into a useEffect in Reactjs?

i'm creating a store that when u click on the button you'll be redirected to paypal, but i came across a doubt about how i could pass my value of the cost into the button but first of all into the value amount of paypal?
the data is taken from the database using mysql and then axios, as u can see i used a map and named val with the variable of database:
That's my code:
import React,{useState, useEffect, useRef} from 'react'
import Axios from 'axios'
import Navbar from '../Navbar/Navbar'
import styled from 'styled-components'
import { Desc } from '../Store/Desc'
import { ButtonStore } from '../Buttons/Button/Button'
import './Store.css'
function Store() {
const [cards, setCards] = useState([])
const [payValue, setPayValue] = useState("");
const paypal = useRef()
useEffect(() => {
Axios.get("http://localhost:3001/gems", {
}).then((response) => {
setCards(response.data);
})
}, [])
useEffect(() => {
window.paypal.Buttons({
createOrder: (data, actions, err) => {
return actions.order.create({
intent: "CAPTURE",
purchase_units: [{
description: 'Points',
amount: {
currency_code: "EUR",
value: // HERE IS WHERE I WANT TO DEFINE THE VALUE WHEN I CLICK THE BUTTON
}
}]
})
},
onApprove: async(data, actions) => {
const order = await actions.order.capture()
console.log(order)
},
onError: (err) => {
console.log(err)
}
}).render(paypal.current)
}, [])
return (
<>
<Navbar/>
<HeroContainer>
<HeroBg>
</HeroBg>
<HeroContent>
<HeroItems>
<HeroH1>get more points and unlock new content!</HeroH1>
<HeroH6>Gems</HeroH6>
{cards.map((val) => {
const a = val.Price1;
return(
<div className="flex">
<div className="columns">
<ul className="price">
<li className="header"></li>
<li className="grey">$ {val.Price1}</li>
<li>{val.Point1}</li>
<ButtonStore value={a}/> //That's my button where i tried to pass the value
</ul>
</div>
<div className="columns">
<ul className="price">
<li className="header"></li>
<li className="grey">$ {val.Price2}</li>
<li>{val.Point2}</li>
<ButtonStore/>
</ul>
</div>
<div className="columns">
<ul className="price">
<li className="header"></li>
<li className="grey">$ {val.Price3}</li>
<li>{val.Point3}</li>
<ButtonStore value={val.Price3}/>
</ul>
</div>
<div className="columns">
<ul className="price">
<li className="header"></li>
<li className="grey">$ {val.Price4}</li>
<li>{val.Point4}</li>
<ButtonStore/>
</ul>
</div>
<div className="columns">
<ul className="price">
<li className="header"></li>
<li className="grey">$ {val.Price5}</li>
<li>{val.Point5}</li>
<ButtonStore/>
</ul>
</div>
<div className="columns">
<ul className="price">
<li className="header"></li>
<li className="grey">$ {val.Price6}</li>
<li>{val.Point6}</li>
<ButtonStore/>
</ul>
</div>
</div>
)})}
</HeroItems>
</HeroContent>
<div className="Paypalinv">
<div ref={paypal}></div>
</div>
</HeroContainer>
</>
)}
export default Store
So how can i pass the value of my price to the button and then into the amount of paypal? thanks!!

The onClick on the unodered list is not working?

The on onclick function which should call the function which is HTML inside Java-script (JSX). Does not seems to work??
Does onClick only works on a button or does it also work on the lists too?
class Top extends React.Component{
constructor(){
super();
this.searchjsx = this.searchjsx.bind(this);
}
searchjsx = () =>{
return(
<div id='searchdiv'>
<form id='searchform'>
<input type="text" id="input" name="search"></input>
</form>
</div>
);
}
render(){
return(
<div>
<div id="navbar">
<ul id="nav">
<li><a className="a" href='https://www.google.com/'>Home</a></li>
<li><a className="b" href='https://www.google.com/'>Profile</a></li>
<li><a className="c" href='https://www.google.com/'>Pricing</a></li>
<li onClick={this.searchjsx} id='sch'>Search..</li>
</ul>
</div>
<div>
</div>
</div>
);
}
}
The below worked for me:
import React from "react";
export default class Top extends React.Component {
state = {
showForm: false
};
searchjsx = () => {
console.log("Toggled showForm");
this.setState({ showForm: !this.state.showForm });
};
render() {
return (
<div>
<div id="navbar">
<ul id="nav">
<li>
<a className="a" href="https://www.google.com/">
Home
</a>
</li>
<li>
<a className="b" href="https://www.google.com/">
Profile
</a>
</li>
<li>
<a className="c" href="https://www.google.com/">
Pricing
</a>
</li>
<li onClick={this.searchjsx} id="sch">
Search..
</li>
{this.state.showForm ? (
<div id="searchdiv">
<form id="searchform">
<input type="text" id="input" name="search"></input>
</form>
</div>
) : (
""
)}
</ul>
</div>
<div></div>
</div>
);
}
}
Notes:
onclick should work on any element
You were trying to insert the form inside the onClick attribute. Instead, you should change the state of the component when li is clicked and based on the state show or hide the form
You don't seem to need a constructor in this example
import React from "react";
export default class Top extends React.Component{
state = {
show:false
}
showInput() {
return(
<div id='searchdiv'>
<form id='searchform'>
<input type="text" id="input" name="search"></input>
</form>
</div>
);
}
handleShow() {
this.setState({
show: !this.state.show
})
}
render(){
return(
<div>
<div id="navbar">
<ul id="nav">
<li><a className="a" href='https://www.google.com/'>Home</a></li>
<li><a className="b" href='https://www.google.com/'>Profile</a></li>
<li><a className="c" href='https://www.google.com/'>Pricing</a></li>
<li onClick={e => this.handleShow(e)} id='sch'>Search..</li>
{
this.state.show ? this.showInput() : null
}
</ul>
</div>
</div>
);
}
}
You have to maintain a state variable that can control when to display a component. In this case, show.

how to rendering element in state React JS?

i have a trouble at the moment will rendering html tag inside state. When i add 'div dangerouslySetInnerHTML={{__html: this.state.actions}} it seems can't because i will render in li tag for menu
this.state = {
sideBar : '<li>[object Object]</li>'
}
// when i render
render(){
return(
{ this.state.sideBar}
) ==> // '<li>[object Object]</li>'
// what should happen is to create a new list
[object Object]
You can get it working without using dangerouslySetInnerHTML. Here's an example of using <ul> and an array of <li> tags that you can render directly in React.
class App extends Component {
constructor(props) {
super(props);
this.state = {
list: ["list 1", "list 2", "list 3"]
};
}
render() {
return (
<div>
<ul>
{this.state.list.map((obj, index) => <li key={index}>{obj}</li> )}
</ul>
</div>
);
}
}
like this code
import React, { Component } from 'react'
import { Route, NavLink, Link } from 'react-router-dom'
import ReactTimeout from 'react-timeout'
class Menu extends Component {
constructor() {
super();
this.state = {
menuBar: [],
sideBar: []
}
}
async componentDidMount() {
const res = await fetch('http://localhost:3001/api/menu/' + 18)
const something = await res.json()
this.setState({ menuBar: something })
console.log(this.state.menuBar)
let menuBar = this.state.menuBar
let html = "";
let link_menu = []
for (var i = 0; i < menuBar.length; i++) {
if (menuBar.menu_url == 'dashboard' || menuBar.menu_flag_link === 1) {
var span_selected = ''
} else {
var span_selected = 'arrow'
}
if (menuBar.menu_flag_link == 0) {
var title_menu = menuBar[i].menu_title
link_menu =
<NavLink
to='javascript:;'
exact>title_menu</NavLink>
} else {
var title_menu = menuBar[i].menu_title
link_menu = <NavLink
to="/"
exact>title_menu</NavLink>
}
html += '<li>' + link_menu
if (menuBar[i].child.length > 0) {
html += "<ul class='sub-menu'>"
for (var j = 0; j < menuBar[i].child.length; j++) {
if (menuBar[j].child.menu_flag_link == 0) {
var link_menu2 = <NavLink
to='javascript:;'
exact>menuBar.child.menu_title</NavLink>
} else {
var link_menu2 =
<NavLink
to="/"
exact>menuBar.child.menu_title</NavLink>
}
html += "<li>, ${link_menu2}"
if (menuBar[i].child[j].length > 0) {
html += "<ul class='sub-menu'>"
for (var kjh = 0; kjh < menuBar[i].child[j].length; kjh++) {
var link_menu3 =
<NavLink
to="/"
exact>menuBar.child.menu_title</NavLink>
html += '<li> ${link_menu3} </li>'
}
html += '</ul>'
}
html += '</li>'
}
html += '</ul>'
}
html += '</li>'
}
this.setState({ sideBar: html })
}
render() {
let menuBar = this.state.menuBar
let sideBar = this.state.sideBar
// console.log(sideBar)
return (
<div class="page-sidebar-wrapper">
<div class="page-sidebar navbar-collapse collapse">
<ul class="page-sidebar-menu page-sidebar-menu-light" data-keep-expanded="true" data-auto-scroll="true" data-slide-speed="200">
<li class="sidebar-toggler-wrapper">
<div class="sidebar-toggler">
</div>
</li>
<li class="sidebar-search-wrapper">
<form class="sidebar-search " action="extra_search.html" method="POST">
<a href="javascript:;" class="remove">
<i class="icon-close"></i>
</a>
<div class="input-group">
<input type="text" class="form-control" placeholder="Search..." />
<span class="input-group-btn">
<i class="icon-magnifier"></i>
</span>
</div>
</form>
</li>
<li class="start active open">
<a href="javascript:;">
<i class="icon-home"></i>
<span class="title">Dashboard</span>
<span class="selected"></span>
<span class="arrow open"></span>
</a>
<ul class="sub-menu">
<li>
<NavLink
to="/"
exact>Home</NavLink>
</li>
<li class="active">
<NavLink to={{
pathname: '/blog',
hash: '#submit',
search: '?quick-submit=true'
}}
>Blog</NavLink>
</li>
<li>
<NavLink to={{
pathname: '/Table'
}}>Table</NavLink>
</li>
<li>
<NavLink to={{
pathname: '/BCC'
}}>BCC</NavLink>
</li>
</ul>
</li>
{this.state.sideBar}
<li>
<a href="javascript:;">
<i class="icon-folder"></i>
<span class="title">Multi Level Menu</span>
<span class="arrow "></span>
</a>
<ul class="sub-menu">
<li>
<a href="javascript:;">
<i class="icon-settings"></i> Item 1 <span class="arrow"></span>
</a>
<ul class="sub-menu">
<li>
<a href="javascript:;">
<i class="icon-user"></i>
Sample Link 1 <span class="arrow"></span>
</a>
<ul class="sub-menu">
<li>
<i class="icon-power"></i> Sample Link 1
</li>
<li>
<i class="icon-paper-plane"></i> Sample Link 1
</li>
<li>
<i class="icon-star"></i> Sample Link 1
</li>
</ul>
</li>
<li>
<i class="icon-camera"></i> Sample Link 1
</li>
<li>
<i class="icon-link"></i> Sample Link 2
</li>
<li>
<i class="icon-pointer"></i> Sample Link 3
</li>
</ul>
</li>
<li>
<a href="javascript:;">
<i class="icon-globe"></i> Item 2 <span class="arrow"></span>
</a>
<ul class="sub-menu">
<li>
<i class="icon-tag"></i> Sample Link 1
</li>
<li>
<i class="icon-pencil"></i> Sample Link 1
</li>
<li>
<i class="icon-graph"></i> Sample Link 1
</li>
</ul>
</li>
<li>
<a href="#">
<i class="icon-bar-chart"></i>
Item 3 </a>
</li>
</ul>
</li>
</ul>
</div>
</div>
)
}
}
export default ReactTimeout(Menu)

Meteor & React with reactive styling

Being new to both Meteor and React, I'm going about this is a non-reactive way and I know it's incorrect, but I'm having a hard time figuring out what the proper way to do this might be.
1) logIn and logOut variables should be a function, I think, but I'm not clear on how to put a function in a render.
2) Meteor.logout(document.location.reload());, seems incorrect.
I feel like I could merge these two concepts into one.
export default class Header extends React.Component {
render() {
$(".button-collapse").sideNav();
var navStyle = {
backgroundColor: "#263238",
paddingLeft: "10px"
};
var logIn = {
display: (Meteor.userId() ? "none" : "block")
};
var logOut = {
display: (Meteor.userId() ? "block" : "none")
};
return (
<nav style={navStyle}>
<div>
ShortShape
<i className="material-icons">menu</i>
<ul className="right hide-on-med-and-down">
<li>Home</li>
<li style={logOut}>Logout</li>
<li style={logIn}>Register</li>
<li style={logIn}>Login</li>
<li>Stories</li>
</ul>
<ul className="side-nav" id="mobile-demo">
<li>Home</li>
<li style={logOut}>Logout</li>
<li style={logIn}>Register</li>
<li style={logIn}>Login</li>
<li>Stories</li>
</ul>
</div>
</nav>
);
}
}
In order to make your component renders reactively, you need to wrap it in a reactive container. There are quite a lot reactive container out there, but I usually use createContainer which is the official container from Meteor team
import { createContainer } from 'meteor/react-meteor-data';
class Header extends React.Component {
logout() {
Meteor.logout(() => {
window.location.reload();
});
}
render() {
const user = this.props.user;
$(".button-collapse").sideNav();
var navStyle = {
backgroundColor: "#263238",
paddingLeft: "10px"
};
var logIn = {
display: (user ? "none" : "block")
};
var logOut = {
display: (user ? "block" : "none")
};
return (
<nav style={navStyle}>
<div>
ShortShape
<i className="material-icons">menu</i>
<ul className="right hide-on-med-and-down">
<li>Home</li>
<li style={logOut}>
<a onClick={this.logout}>Logout</a>
</li>
<li style={logIn}>Register</li>
<li style={logIn}>Login</li>
<li>Stories</li>
</ul>
<ul className="side-nav" id="mobile-demo">
<li>Home</li>
<li style={logOut}>
<a onClick={this.logout}>Logout</a>
</li>
<li style={logIn}>Register</li>
<li style={logIn}>Login</li>
<li>Stories</li>
</ul>
</div>
</nav>
);
}
}
export default createContainer(() => {
// this function will run reactively
return {
user: Meteor.user(),
};
}, Header);

Categories