Building a timer using Vue.js and moment.js

I'm currently working on a timer using vue.js and moment.js which specifically focuses on minutes and seconds. My code should technically work as intended, however it's not yielding the desired results:

var app = new Vue({
  el: '#app',
  data: {
    date: moment(60 * 10 * 1000)
  },
  computed: {
    time: function(){
      return this.date.format('mm:ss');
    }
  },
  mounted: function(){
    var aa = this.date;
    
    setInterval(function(){
      aa.subtract(1, 'seconds');
    }, 1000);
  }
});
<script src="https://momentjs.com/downloads/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>

<div id="app">{{ time }}</div>

Answer №1

After @Phil mentioned it, the issue arises from a reactivity problem. The subtract function merely updates some properties and then returns the original object.

Therefore, we need to use a new object to replace the old one. (There might be a way to utilize Vue.set or vm.$set to update the moment object's properties, and hopefully someone can provide guidance on that.)

Here is a demonstration:

var app = new Vue({
  el: '#app',
  data: {
    date: moment(60 * 10 * 1000)
  },
  computed: {
    time: function(){
      return this.date.format('mm:ss');
    }
  },
  mounted: function(){   
    setInterval(() => {
      this.date = moment(this.date.subtract(1, 'seconds'))
    }, 1000);
  }
});
<script src="https://momentjs.com/downloads/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>

<div id="app">{{ time }}</div>

Answer №2

Here's an example of a countdown using Vue with moment:

<script>
new Vue({
el: '#app',
data: {
message: 'Current Time:',
currentTime: null },

methods: {
updateCurrentTime: function updateCurrentTime() {
  this.currentTime = moment().format('LTS');
} },

created: function created() {var _this = this;
this.currentTime = moment().format('LTS');
setInterval(function () {return _this.updateCurrentTime();}, 1 * 1000);
} });

</script>
<section id="app" class="section">
<h3 class="title is-3 shadow" v-text="message"></h3>
<p class="time shadow" v-text="currentTime"></p>
</section>

<style> 
body, html {
width: 100%;
height: 100%; 
}

body {
background: -webkit-linear-gradient(LightSteelBlue, LightSalmon);
background: -o-linear-gradient(LightSteelBlue, LightSalmon);
background: -moz-linear-gradient(LightSteelBlue, LightSalmon);
background: linear-gradient(LightSteelBlue, LightSalmon); 
}

section.section {
display: flex;
flex-direction: column;
align-items: center;
padding-top: 140px;
background: transparent;
}

h3.is-3, p.time {
color: white;
}

h3.is-3:not(:last-child) {
margin: 0;
padding: 0;
}

.time {
font-size: 7em;
}

.shadow {
text-shadow: 0 0 15px rgba(100, 100, 100, 0.35);

</style>

Countdown component for VueJS with momentjs

Check out this reference link

This is an example without Vue, only using moment:

// Get next Sunday
var nextSunday = moment().day(7).format("YYYY-MM-DDT11:00:00Z");

// Convert it back to a moment object
var event = moment(nextSunday);

// Get current time/date
var current = moment();

// Calculate difference between event and current time
var diffTime = event.diff(current);

// Use moment.js to create a duration from the timestamp
var duration = moment.duration(diffTime, 'milliseconds', true);

// Set interval in milliseconds
var interval = 1000;

setInterval(function(){
  duration = moment.duration(duration - interval, 'milliseconds');
  $('#clock').html(
      "<div class=\'days cell\'>"+duration.days()+"<span>days</span></div>" +
      "<div class=\'hours cell\'>"+duration.hours()+"<span>hours</span></div>" +
      "<div class=\'mins cell\'>"+duration.minutes()+"<span>mins</span></div>" +
      "<div class=\'secs cell\'>"+duration.seconds()+"<span>secs</span></div>")
}, interval);
$section-color: #343436;
body {
  background-color: #1d1f20;
  color: #99999d;
}
body * {
  box-sizing: border-box;
}

#clock {
  width: 80%;
  margin: 10em auto;
  text-align: center;
  transform: scale(0.8);
}
#clock .cell {
  display: inline-block;
  width: 80px;
  height: 60px;
  background-color: #1b1b1c;
  position: relative;
  border-radius: 5px;
  margin-right: 5px;
  font-size: 3rem;
  padding-top: 2px;
}
#clock .cell span {
  position: absolute;
  left: 0;
  bottom: -30px;
  clear: both;
  text-align: center;
  text-transform: uppercase;
  width: 80px;
  height: 20px;
  font-size: 10px;
}

body {
  background-color: #1d1f20;
  color: lighten($section-color, 40%);
  
  * {
    box-sizing: border-box;
  }
}

#clock {
  width: 80%;
  margin: 10em auto;
  text-align: center;
  transform: scale(.8);
  

}
  .cell {
    display: inline-block;
    width: 80px;
    height: 60px;
    background-color: darken($section-color, 10%);
    position: relative;
    border-radius: 5px;
    margin-right: 5px;
    font-size: 3rem;
    padding-top: 2px;
    color:white;
  }
  .cell span {
    position: absolute;
    left: 0;
    bottom: -30px;
    clear: both;
    text-align: center;
    text-transform: uppercase;
    width: 80px;
    height: 20px;
    font-size: 10px;
   color:white;
  }
}
 <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.min.js'></script>

<div id="clock"></div>

<div style= "color:white;" id="countdown">

</div>

Answer №3

This issue is related to reactivity. Vue does not automatically detect changes when it comes to method calls involving the moment object.

To resolve this, you should update your code so that the result of the date manipulation is reassigned to the date property. Additionally, ensure that you are cloning the moment instance to treat it as a new value instead of the original instance.

setInterval(() => {
  this.date = this.date.clone().subtract(1, 'seconds')
}, 1000)

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

Execute a setInterval operation, pause it for a duration of 3 seconds, and then resume its execution

A setInterval function is looping through some div classes, and if it encounters a div with a specific class, it should pause for 3 seconds before resuming. I am using the following code to clear the interval: clearInterval(myInterval); However, I nee ...

Remove file from the Request.Files collection

I need assistance with removing an image from Request.Files in my ASP uploader using Javascript. Currently, when a user uploads an image and then removes it, the image is still present in Request.Files upon submission. How can I solve this issue? Here are ...

What is the process of using the split() method to extract specific text from a string in JavaScript?

Working with AngularJS and facing a requirement to extract a specific text from a scope value. Here's my scope value: $scope.myLogMsg = '1111 order is placed by Sukumar Ms(User)'; //output: by Sukumar Ms(User) Desired output: by Sukumar Ms ...

Transforming PHP Arrays into JavaScript Objects

I am facing some challenges with my code due to my limited understanding of JSON and JS. Here's the code snippet I have been working on: $markersData = array(); $x = 0; while ($row = @mysqli_fetch_assoc($result)) { $type = $row['type']; ...

Hiding a div upon submission using jquery validator

I need assistance with a validator that currently hides the submit buttons and displays a "please wait" message after the user clicks submit. The issue is that it also triggers this behavior when a date field validates. Is there a way to modify the code s ...

An improved method for managing asynchronous callbacks and rendering the DOM

I am currently utilizing nodemailer for sending email through reactjs. Below is the snippet of my code: constructor(props) { super(props); this.state = { fullname: "", email: "", companyName: "", phoneNumber: "", me ...

Angular does not always interpret the value returned from a Promise.all call

One of the challenges I'm facing is related to the structure of my controller: controller.things = ['a', 'b', 'c']; controller.loading = true; controller.responses = []; controller.handlePromises = function(){ var pr ...

Issues with Jquery Div sliding transitions from right to left are not functioning correctly

Creating page transitions in jQuery similar to "http://support.microsoft.com/." Encountering an issue where after the page transitions are completed, they start from the left instead of the expected right direction. Referencing this fiddle (Working Code) ...

Guide on sending a PUT request using express.js

Currently delving into node.js and have a query regarding PUT requests I'm able to create an object and see it in the URL. However, I'm unsure of how to write a request to edit it - such as changing the price of a vehicle. Any guidance on writin ...

Uninstalling plugins using vue-cli3

Is it feasible to eliminate plugins and their configurations using vue-cli3 in a pre-existing project? As an illustration, let's say I want to swap out the Mocha unit test plugin with Jest. While I understand how to incorporate and utilize a new plugi ...

Having difficulty performing raycasting on a singular object within a group in three.js to trigger an animation

Having issues with raycasting into a group in my three.js project. The goal is to trigger animations using TweenMax on object click. However, the problem arises when clicking on an object with another object behind it, causing both animations to be trigge ...

The value of the variable remains consistent throughout the .each function when using JQuery's .post() method

I am facing a dilemma with a variable value discrepancy within the $.post function compared to the parent function $(element).each(function. Below is the snippet of my code: $(document).ready(function() { $(".list").each(function() { var a = $(thi ...

ASP.NET file uploads using Ajax - handler unable to detect uploaded files

I am embarking on my first attempt at uploading files through Ajax and .ashx. My browser of choice is FireFox 75.0. Upon inspecting the web console, I set a Breakpoint on frm.append(files[i], files[i].name);. I can see the files being appended to the FormD ...

Enhance the overall appearance of select elements across all components using Material UI's

I'm attempting to change the border color of my outlined select elements using the code below, but it's not working as expected. It seems that the border style is being inherited from the fieldset element. I've experimented with using MuiOut ...

Utilizing GraphicsMagick with Node.js to Extract Page Frames from Multi-Page TIF Files

I am currently working with a JavaScript script that can successfully convert a single page TIF file to JPEG. However, I am facing difficulties in determining whether "GraphicsMagick For Node" (https://github.com/aheckmann/gm) has the capability to extra ...

"Is it possible to make a JSON API call in Node.js before exiting with a SIGINT

In my attempt to configure certain variables and make an API call using the request module before exiting the program, I encountered issues where the function was not being properly executed due to the presence of both SIGINT and exit signals: const reque ...

Error: Attempting to access the 'getCroppedCanvas' property of an undefined value in VueJs

I've been exploring the vue-cropperjs library, but every time I execute the code, I encounter error messages: Uncaught TypeError: Cannot read property 'getCroppedCanvas' of undefined Uncaught TypeError: Cannot read property 'replace&ap ...

Vue 3 list fails to refresh

Using an API, we are retrieving data: <script setup> import { onMounted, inject } from 'vue' let list = []; function initializeData() { axios .post("/some-link/here") .then((response) => { list ...

Dynamic element substitution

Can you provide guidance on how to create a smooth transition in the height of a container based on the child element's height? Currently, my code does not include any animation effects. setTimeout(() => { document.getElementById("page1").st ...

Issue with React-Router-Dom v5 - Trouble encountered when using Switch to map an array of Route components

My issue lies with the implementation of react-router-dom shown in the code snippet below. The problem arises when the Switch function stops working after reaching a certain point in the code (marked as #1). It's perplexing as to why this malfunction ...