Create a JavaScript random quote generator that produces a single quote every day

I have recently developed a random quote generator for my Angular application. The logic within the component is as follows:

qotd = this.quotes[Math.floor(Math.random() * this.quotes.length)];

This code snippet fetches data structured like this:

  quotes = [
    {
      quote: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus euismod magna magna, euismod tincidunt libero dignis.",
      author: 'Sorato Violasa'
    },
    {
      quote: "Nullam dignissim accumsan magna vitae rhoncus. Phasellus euismod magna magna, euismod tincidunt libero dignis.",
      author: 'Vito Dignaora'
    },
    {
      quote: "In tincidunt imperdiet augue, quis sollicitudin mi tincidunt ut.",
      author: 'Hivalo Amettioa'
    },
    {
      quote: "hasellus accumsan erat vitae enim blandit, quis euismod ipsum sollicitudin.",
      author: 'Grasha Plojiva'
    },
  ];

To display the generated quote in the view, I use this code structure:

<div class="quotes">
    <p class="quote">
        {{qotd.quote}} <br><br>
        ~ {{qotd.author}}
    </p>
</div>

Currently, a new quote is displayed every time the component reloads, leading to multiple changes within a single session. However, it would be more beneficial to transform this into a daily quote generator. This way, a new quote will only appear when the date changes. To achieve this, I can easily obtain the current date and day of the week like this:

  date = new Date();
  dayNumber = this.date.getDay();

The question now arises on how to calculate when the day changes and consequently trigger a new quote generation instance?

Answer №1

Imagine a system where the server generates 3 quotes: one for yesterday, today, and tomorrow. With each passing day, yesterday's quote is replaced with a new one for tomorrow. This allows for the client's quote to be updated right after midnight local time, ensuring that everyone sees the same daily message.

Since no place on Earth is more than 14 hours ahead or behind UTC, the server can use UTC as the base time for generating keys. This way, clients will always have access to an appropriate number of quotes without having the entire database sent to them every time there is a change.

var quotes = {
  '20171012':{quote:'one',author:'fred'},
  '20171013':{quote:'two',author:'mary'},
  '20171014':{quote:'three',author:'sue'}
};

function showQuote(quotes) {
  var d = new Date();
  var key = '' + d.getFullYear() +
             ('0'+(d.getMonth()+1)).slice(-2) +
             ('0'+d.getDate()).slice(-2);
  return quotes[key]
}

// On 2017-10-13 shows quote: two, author: mary
console.log(showQuote(quotes));

Answer №2

Hold on... Just a moment ... If you want to assign specific quotes for each day, that's a different situation than selecting a random quote from a list and having it remain the same for 24 hours. Using an array, you can utilize the rand function along with a count of the total values in the array. This will provide a single value each time it is loaded. Additionally, there is another function called srand. When you use srand, you establish a seed that influences the randomization process.

Alright then...

The seed determines the result of srand, which is responsible for the randomness. You could also experiment with the shuffle function, which also relies on a seed.

Now, you'll need to determine a suitable value to serve as the seed, ensuring that this number changes every 24-hour period.

To introduce a timeline, a reference point is necessary. You might consider utilizing server time or user agent time for this purpose.

If you choose the seed '42', you will consistently get the same output from srand.

Let's illustrate this: Imagine you have a list of 42 quotes. Firstly, set up the array, define the seed variable, and extract the value.

$numbers = range(1,42); $seed = floor(time()/86400); The seed value is determined by the server's Unix timestamp, making it timezone-independent (=UTC). To represent a daily interval, calculate based on 86400 seconds, equivalent to one day. Randomize the array shuffle($numbers); and display the initial outcome. Now let's suppose we are dealing with a list of 200 quotes:

$quoteslist= range(1,200);
$seed = floor(time()/86400);
echo $seed;

$resultado = $quoteslist;
$seed = floor(time()/86400);
 shuffle($resultado);
echo $resultado[$i];

The value generated by time(), known as the timestamp, has been converted into 18846 serving as today's seed.

This seed is utilized to shuffle the list effectively.

Showcasing the first result.

// Determine the array count. Let's create a 200-quote array.
$quotes = range(1,200);
$seed = floor(time()/86400);
echo 'the seed is:'. $seed.' and it changes daily.';
echo '<hr>';

// Create another range using the same index
$quotes = range(1,200); 
$resultado = $quotes;

// Display the first value without shuffling (which should be 1)
echo 'the first result of the range array : ';
echo $resultado[0];
echo '<hr>';

// Echo the shuffled result without using srand and seed, showing a different value each time
$quotes = range(1,200); 
$resultado = $quotes;
shuffle($resultado);
echo 'first result of the array, randomly shuffled.. but not seeded:  ';
echo $resultado[0];
echo '<br> this changes with each refresh';
echo " <hr> ";


// Generate a new random number each day utilizing a seed 

$quotes = range(1,200);
$resultado = $quotes;
echo 'today: ';
$seed = floor(time()/86400);
srand($seed);
shuffle($resultado);
echo $resultado[0];
echo " * this changes daily, providing the same outcome upon reloads  <hr> ";

echo '<br>';
// Today's seed  
$quotes = range(1,200);
$resultado = $quotes;
echo 'the seed for today - 18846: result remains constant throughout the day, due to the specified seed : ';
srand(18846);
shuffle($resultado);
echo $resultado[0];
echo " <hr> ";

echo 'result for seed 18847 , tomorrow - consistent outcome : ';
$quotes = range(1,200);
$resultado = $quotes;
// This reflects data two days later
srand(18847);
shuffle($resultado);
echo $resultado[0];

Answer №3

If you're looking for a strategy to track the current day, one option is to use the client-side storage feature called localStorage. Within your component, you can first check if the currentDay key exists in the localStorage. If it doesn't, you can create it and store both the currentDay value and the qotd within an object.

When you revisit your component later on, the qotd should already be saved in the localStorage. You can then compare the saved date with the current date we generate to determine if a new day has begun.

//PSEUDOCODE (not tested)
function(){
  this.qotd = this.quotes[Math.floor(Math.random() * this.quotes.length)];

  if(!window.localStorage.getItem('todayDate')){
    let currentDay = new Date().getDay();
    let storageItem = JSON.stringify({
      currentDay,
      qotd: this.qotd
    })
    window.localStorage.setItem('currentDay',storageItem)
  } 
  else {
    var existingQOTD = JSON.parse(window.localStorage.getItem('todayDate'));
    let currentDay = new Date().getDay();
    if(existingQOTD.currentDay !== currentDay){
      let storageItem = JSON.stringify({
        currentDay,
        qotd: this.qotd
      })
      window.localStorage.setItem('currentDay', storageItem)
    }
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the process for including a task in the current method?

I've been working on building a web app similar to Google Calendar. I have successfully created the necessary objects and methods, but now I need to implement a feature that allows users to add tasks. My current idea is for users to input a task which ...

Is it possible to include additional information when creating a subscription for a customer on Stripe using Node.js

I am facing an issue with adding metadata to the customer object during the creation of a new subscription/customer using Stripe. The problem lies in the fact that the metadata is not being saved to the customer object. I have checked the logs/events in St ...

What is the process of converting a `typeorm` model into a GraphQL payload?

In my current project, I am developing a microservice application. One of the services is a Node.js service designed as the 'data service', utilizing nestjs, typeorm, and type-graphql models. The data service integrates the https://github.com/nes ...

Boosting Website Loading Time with Puppeteer: A Guide

Currently, I am using Puppeteer for automating tasks and it is working well. However, I have noticed that when loading the website, it takes longer than my usual websites. I attempted to use caching with the following code: const puppeteer = require(' ...

The Angular application is not functioning properly after refreshing the web browser

My angularJS app runs smoothly up until I refresh my web browser. Within my application, there is a JSON object retrieved during login that includes a session ID and an array. However, upon refreshing the page, the JSON object becomes empty and errors sta ...

Utilizing JavaScript to transmit checkbox values to a database

I am both intrigued and confused by the power of checkboxes. I want to use them to allow customers to select their preferred type of cuisine (fast food, Italian, sushi, etc.). Ultimately, I plan to match these preferences with restaurants offering those ty ...

Is it possible to target a specific element using Angular2's HostListener feature? Can we target elements based on their class name?"

Is there a way in Angular2 to target a specific element within the HostListener decorator? @HostListener('dragstart', ['$event']) onDragStart(ev:Event) { console.log(ev); } @HostListener('document: dragstart' ...

Creating formGroups dynamically within an ngFor loop inside an accordion

I am facing a challenge with an accordion feature that generates a specified number of sections x based on user input. Here is an example: https://i.sstatic.net/QjmkW.png After creating the sections, I need to load employee information into each section ...

Can you create a dynamic visual display using HTML5 Canvas to draw lines in a circular pattern that react

I have successfully implemented drawing lines around a circle using the AudioContext API. However, I am facing an issue with the lineTo function, as the line only grows and does not shrink. My inspiration for this project comes from the audio visualizer fo ...

Looking for an IOS yearly calendar solution for Angular6? Look no further than the angular-calendar-year-view library available at [https://github.com/MariemChaab

Seeking an angular yearly calendar for iOS similar to the one found at [https://github.com/MariemChaabeni/angular-calendar-year-view], designed for use with Angular 7. However, when attempting to integrate it into Angular 6, I encountered error ts1005; e ...

The issue of an undefined Node.js variable post "await"

While I know similar questions have been asked before, I assure you that I've gone through them; however, I'm still facing a challenge. I have a simple code snippet to retrieve a token for a 3rd-party API service: let tok = ''; const g ...

Using Node's Express bodyParser() to access a JSON string that has been parsed

Question: How can I retrieve the parsed JSON object from the server side? I have successfully sent a JSON string to the server, but I am having trouble accessing the object once it is parsed. The client-side script for sending the JSON data is as follows ...

Exploring yii2 with javascript to display image previews

I am looking to add a feature to my yii2 app similar to this: How to preview multiple images before upload?. I want to display up to five images but my current code is not working. When I select a file, nothing happens. <?php use yii\helpers\ ...

GSAP also brings scale transformations to life through its animation capabilities

I have an SVG graphic and I'm looking to make four elements appear in place. I've been using GSAP, but the elements seem to be flying into place rather than scaling up. Here's the code snippet I've been using: gsap.fromTo( ...

Learn the process of inserting a table in ExcelJS specifically for Angular applications

I encountered an issue when attempting to add a table with data. An error message stating "AddTable is not function" appeared. let workbook = new ExcelJS.Workbook(); let worksheet = workbook.addWorksheet("Data"); worksheet.addTable({ name: 'My ...

The useEffect hook is not successfully fetching data from the local db.json file

I'm attempting to emulate a Plant API by utilizing a db.json file (with relative path: src\plant-api\db.json), and passing it from the parent component (ItemList) to its child (Item) but I am facing an issue where no data is being displayed ...

SQL - Establishing time frame for data collection across multiple datasets

I am working with three different tables named Table_A, Table_B, and Table_C. Each of these tables contains three specific variables - ID, Problem, and Date. The presence of the date variable can vary across the tables. The goal is to create a new table ...

What steps should I take to fix the following error: TypeError: undefined is not an object when trying to evaluate '_bip.default.generateMnemonic'?

I'm in the process of developing a mobile application and I find myself in need of utilizing bip39 for passphrase generation. However, after installing the necessary package, I encountered errors related to missing packages like stream buffer events. ...

The AngularJS price slider may exceed its range if the ng-model is null or below the minimum value

I currently have an rz-slider featured on my webpage that is utilized for gathering the price of a product from the user. In addition to the slider, there are two input fields present which are designated for storing the minimum and maximum values. The ng- ...

Ways to delete the title from a box in orgChart

Is there a way to remove the title from the box and only show the content? I've searched extensively but haven't found a solution yet. I'm currently using orgChart: https://github.com/dabeng/OrgChart For example, the general manager box s ...