I'm making a random color of the day web application using a random color API I found online. Everything is working so far, but since I'm new to JavaScript and React, I'm a bit curious on how I would limit an API request to once per day. The way the API works now is that every time you refresh the page, a new color will appear every time. Is there any way to limit this to one color that will appear per day - the same color - no matter how many times you refresh the page? Thanks!
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor() {
super()
this.state = {
items: [],
isLoaded: true
}
}
ponentDidMount() {
fetch("")
.then(res => res.json())
.then(res => {
this.setState({
isLoaded: true,
items: res.colors
});
})
}
render() {
var itemName = this.state.items.map(item => item.id)
var itemHex = this.state.items.map(item => item.hex)
//var itemHex = items.map(item => <div key={item.id}>{item.hex}</div>)
if (!(this.state.isLoaded)) {
return (
<div>
<h1>Not Loaded!</h1>
</div>
)
}
else {
return (
<section style={{ backgroundColor: "#" + itemHex[0]}} className="App">
<h1>JR's color of the day is: <h2 style={{color: "#" + itemHex[4]}}>{itemName[0]}.</h2></h1>
<h1>also, the hex is: {"#" + itemHex[0]}</h1>
<h4>here are some other colors that go w/ it</h4>
<div style={{backgroundColor: "#" + itemHex[1]}} className="rectangle1"></div>
<div style={{backgroundColor: "#" + itemHex[2]}} className="rectangle2"></div>
<div style={{backgroundColor: "#" + itemHex[3]}} className="rectangle3"></div>
<h3><a href=".html">data courtesy of the color API, colr</a></h3>
</section>
);
}
}
}
export default App;
I'm making a random color of the day web application using a random color API I found online. Everything is working so far, but since I'm new to JavaScript and React, I'm a bit curious on how I would limit an API request to once per day. The way the API works now is that every time you refresh the page, a new color will appear every time. Is there any way to limit this to one color that will appear per day - the same color - no matter how many times you refresh the page? Thanks!
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor() {
super()
this.state = {
items: [],
isLoaded: true
}
}
ponentDidMount() {
fetch("http://www.colr/json/colors/random/7")
.then(res => res.json())
.then(res => {
this.setState({
isLoaded: true,
items: res.colors
});
})
}
render() {
var itemName = this.state.items.map(item => item.id)
var itemHex = this.state.items.map(item => item.hex)
//var itemHex = items.map(item => <div key={item.id}>{item.hex}</div>)
if (!(this.state.isLoaded)) {
return (
<div>
<h1>Not Loaded!</h1>
</div>
)
}
else {
return (
<section style={{ backgroundColor: "#" + itemHex[0]}} className="App">
<h1>JR's color of the day is: <h2 style={{color: "#" + itemHex[4]}}>{itemName[0]}.</h2></h1>
<h1>also, the hex is: {"#" + itemHex[0]}</h1>
<h4>here are some other colors that go w/ it</h4>
<div style={{backgroundColor: "#" + itemHex[1]}} className="rectangle1"></div>
<div style={{backgroundColor: "#" + itemHex[2]}} className="rectangle2"></div>
<div style={{backgroundColor: "#" + itemHex[3]}} className="rectangle3"></div>
<h3><a href="http://www.colr/api.html">data courtesy of the color API, colr</a></h3>
</section>
);
}
}
}
export default App;
Share
Improve this question
asked Mar 10, 2019 at 2:07
Laurel LinkLaurel Link
3051 gold badge6 silver badges17 bronze badges
3
- 2 You may use a cookie to store one color per day. – A.L Commented Mar 10, 2019 at 2:13
- Any tips or links on how I might do that? – Laurel Link Commented Mar 10, 2019 at 2:26
- If you performed the calculations on the server, then it could probably work, or you could consider storing some identifier per user in a database, in addition to the time of visit. Basic example: Storing their IP address, and then storing the served API result in the database. – Keno Commented Mar 10, 2019 at 3:56
4 Answers
Reset to default 3How to limit an API request to once per day in React?
You can't, really. Rate-limiting an API is done on the server. Anybody can clear their cookies, or local storage, or whatever other means of persistence you use in the browser to rate-limit requests.
I realize this is a learning exercise, but there is no point in learning a technique that has no real-world use.
you just need to store the date and colors on each fetch. and invalidate your cache based on today's date string and stored one.
ponentDidMount() {
let cachedColors;
if(localStorage.getItem('cached-colors'))
cachedColors = JSON.parse(localStorage.getItem('cached-colors'));
// setting cachedColors to null if it wasn't stored today
if(cachedColors && new Date().toDateString() !== cachedColors.date)
cachedColors = null;
// if cachedColors still got value, it means we can use it as valid cache for today
if(cachedColors)
this.setState({
isLoaded: true,
items: cachedColors.value
});
else
fetch("http://www.colr/json/colors/random/7")
.then(res => res.json())
.then(res => {
this.setState({
isLoaded: true,
items: res.colors
});
})
}
https://www.npmjs./package/memory-cache is the solution. Here are the examples of the API Usage.
This does what you're looking for by storing the current color in the browser for one day. The code should be clear, but just ask if it's not.
(Tested in Chrome with a Node backend, but should be fine in React)
let now = new Date().getTime(); // number of milliseconds since the 60's ended in London
const oneDay = 1000 * 60 * 60 * 24; // number of milliseconds in a day
if(localStorage.color && localStorage.expireTime && parseInt(localStorage.expireTime) > now){
let storedColor = localStorage.color; // or localStorage.getItem("color")
console.log(`Returning user -- Color from last visit is ${storedColor}`);
}
else{
let newColor = "green"; // Set your new color here
let newExpireTime = now + oneDay;
localStorage.setItem("color", newColor);
localStorage.setItem("expireTime", newExpireTime);
let dateString = new Date(newExpireTime).toLocaleString();
console.log(`First visit (since storage was cleared). New color, ${newColor}, will be replaced at ${dateString}`);
}
(Edit: Removed html output and added the info to console.log instead,
removed 'localStorage.clear()', which was for debugging)