Countdown on Ionic 2 - angularjs

ionViewDidEnter() {
//----------------------------------------------------------------------LISTAGEM ALMOÇOS--------------------------------------------------------------------------------------
let data = JSON.stringify({id: this.id});
let link = *;
this.http.post(link,data)
.map(res => res.json())
.subscribe(data=>{
console.log(data);
this.almocos = [];
//IDs das conversas
for (var a = 0; a < data.length; a++){
this.foto2 = data[a][2];
if(Number.isInteger(data[a][7])){
console.log(data[a][7])
this.tempo[0] = data[a][7] + "dias"
this.tempo[1] = "";
this.tempo[2] = "";
}else {
this.tempo = data[a][7].split(":");
this.tempo[0] = this.tempo[0] + ":";
this.tempo[1] = this.tempo[1] + ":"
}
this.tempos = [];
this.foto =[];
let cor;
let pessoas;
let forma;
if (data[a][4].length == 1){
if(data[a][5]== this.nome){
data[a][2]= data[a][4][0][1]
}
pessoas = data[a][4][0][0];
this.foto.push(data[a][4][0][1]);
} else if (data[a][4].length == 2) {
pessoas = data[a][4][0][0] + " e " + data[a][4][1][0];
this.foto.push(data[a][4][0][1]);
this.foto.push(data[a][4][1][1]);
} else {
pessoas = data[a][4][0][0] + " e " + (data[a][4].length-1) + " pessoas"
for (var i = 0; i < data[a][4].length; i++){
this.foto.push(data[a][4][i][1]);
}
}
if(data[a][4].length > 1){
if(data[a][6] == 1){
data[a][2] = "social.png";
cor= "#e73C58";
forma = "S"
} else if (data[a][6] == 2){
data[a][2] = "profissional.png";
cor= "#1ab2bc";
forma = "P";
}else if (data[a][6] == 3){
data[a][2] = "academico.png";
cor= "#9b59b6";
forma = "A";
}
}else{
if(data[a][6] == 1){
cor= "#e73C58 ";
forma = "S"
} else if (data[a][6] == 2){
cor= "#1ab2bc ";
forma = "P";
}else if (data[a][6] == 3){
cor= "#9b59b6";
forma = "A"
}
}
this.cores = "#ffffff";
this.almocos.push(
{
id : data[a][0],
dia : data[a][1],
foto : data[a][2],
foto_anf: this.foto2,
estrelas : data[a][3],
pessoal : pessoas,
tipo : cor,
forma :forma,
fotos : this.foto,
segundo : this.tempo[2],
minuto : this.tempo[1],
horas : this.tempo[0]
});
setInterval(function(){
console.log("segundos");
let segundos;
let minutos;
let hora;
segundos--;
if (segundos == 0){
segundos = 60;
minutos--;
}
if (minutos == 0){
minutos = 59;
hora--;
}
segundos-- ;
this.tempos = [];
this.tempos.push(segundos);
}, 1000);
}
}, error =>{
console.log("erro")
});
//----------------------------------------------------------------------FIM LISTAGEM ALMOÇOS--------------------------------------------------------------------------------------
}
<div style="float:right;position:relative;left:0px;position:relative;top:3px">
<span><ion-icon style="font-size:14px;" name="md-time"></ion-icon><span style="font-size:13px;position:relative;bottom:1px;margin-left:2px"> {{almoco.horas}}{{almoco.minuto}}{{almoco.segundo}} </span></span>
</div>
The variables are hours, minutes and seconds. Each is related to a date in the database, where we get the time remaining. I'd like to be able to show in real-time a countdown until the actual date.
I know it's possible via Observable, but I can't figure out how. An answer with integer variables (e.g. hours= 23; minutes=14; seconds=19) would be ideal, so I can just attribute the values from the database.
Thanks in advance!

I noticed some issues in your code that could help you to solve your problem:
You should avoid to change the data object itself and instead create a copy and work with that. That way you always know what the server responded with and what you changed.
You have a lot of "hardcoded" array indexes. If you have control over the backend, you should try to avoid that and instead use an object with named properties. So instead of doing
this.push(data[a][4][0][1]);
you could do something like
data[a].almoco.photoUrl // Depending on what you want to do, obviously
which looks a lot nicer and gives you more readable code.
Now to your countdown problem:
First of all, you have your setInterval inside your for loop, which means that the setInterval is called multiple times per second. (At least as many times as you have elements in your array).
You also define
let segundos;
let minutos;
let hora;
but never assign them a value, so your if-checks will always be wrong.
You should also avoid calculating the time when you get the response from the server and instead store the end-time you get from the server as a javascript date.
Once you have that, you can either calculate the difference manually in your setInterval (end-date - current date, make sure you call it only once) and use a custom angular pipe to convert the seconds to a nice format, or use an npm nodule like this: https://github.com/previousdeveloper/angular2-simple-countdown

Related

Problems with includes() function and array comparsion

As a part of whole procedure, I want to compare user's input (as array) with union of two randomly given arrays. I can not use array.sort() and comparison of arrays element by element, because it's enough to have just one different element in input array and after sorting more than just one element will be identified as "wrong one" (example: array "union" after sorting = [11,13,17,18], array "upis" (user's input) after sorting = [7,11,13,18] so if I compare element by element, which I've tried in original code, all first three elements are identified as wrong...)
That's why I've switched to array.includes() and I've spend last 5.5 hours trying to find where am I wrong and just can't find it so I'm going slightly mad... In few hours I'm supposed to be at work but I'm losing my mind because of this...
THE PROBLEM IS WITHIN checkInput() FUNCTION... The code just won't and won't recognize input elements (array "upis") within "union" array... Can't figure out why???
Any help more then appreciated!
<script>
//----------- 1.) Kreiraj dva nasumična niza i uniju -----------
var arrA = []; //od 3 do max 6 članova
var arrB = []; //od 2 do max 5 članova
while (arrA.length < Math.floor(Math.random() * 4) + 3) {
var randomnumber = Math.floor(Math.random() * 20) + 1;
if (arrA.indexOf(randomnumber) > -1) continue;
arrA[arrA.length] = randomnumber;
}
while (arrB.length < Math.floor(Math.random() * 4) + 2) {
var randomnumber = Math.floor(Math.random() * 20) + 1;
if (arrB.indexOf(randomnumber) > -1) continue;
arrB[arrB.length] = randomnumber;
}
var union = [...new Set([...arrA, ...arrB])];
document.write("A = " + arrA + "<br>");
document.write("B = " + arrB + "<br>");
//----------- 2.) Funkcija za dodavanje text box-ova -----------
function addFields() {
// Broj text box-ova koje treba kreirati
var number = union.length;
// <div> u koji će se dinamično dodati text box-ovi
var container = document.getElementById("container");
// Obriši prethodni zapis u <div>
while (container.hasChildNodes()) {
container.removeChild(container.lastChild);
}
// Tekst A U B
//container.appendChild(document.createElement("br"));
container.appendChild(document.createTextNode("A ∪ B = "));
for (i = 0; i < number; i++) {
// Kreiraj <input> element i definiraj stil
var input = document.createElement("input");
input.type = "text";
input.id = "element" + i;
input.style.width = 25;
container.appendChild(input);
// Dodaj zarez poslije svakog input box-a, osim posljednjeg
if (i < number - 1) {
container.appendChild(document.createTextNode(", "));
}
}
// Pokaži gumb Provjeri
document.getElementById("provj").style.visibility = "visible";
}
//----------- 3.) Provjera upisa -----------
function checkInput() {
var upis = [];
var greske = [];
// Pohrani upis u niz
for (i = 0; i < union.length; i++) {
var privr = document.getElementById("element" + i).value;
upis.push(privr);
}
for (i = 0; i < upis.length; i++) {
// ako je neko polje nepopunjeno, obavijesti i prekini petlju
if (upis[i] === "") {
alert("Treba upisati sve članove unije skupova!");
greske = [];
//npr. prva dva upisa kriva, ostala polja nepopunjena - iako ima
//praznih polja, prekida se procedura ali se kod prva dva upisa
//popunio niz greške i onda će ih pokazati
break;
}
// u protivnom
else {
var n = union.includes(upis[i]);
alert(upis[i] + " " + n);
if (n === false) {
greske.push(upis[i]);
} else {
//ništa
}
}
}
if (greske.length > 0) {
alert("Krivo upisani članovi: " + greske);
}
}
</script>
<div id="container">
<button onclick="addFields()">Upiši članove unije</button>
</div>
<button id="provj" style="visibility:hidden" onclick="checkInput()">Provjeri</button>
You are comparing numbers with strings. Just add + to the includes parameter:
var n = union.includes(+upis[i]);
This will force the string to be unboxed as a number and your includes will work as expected.
You other option is to convert those strings to numbers and then no unboxing will be needed.

Having an issue figuring out where to do calculations before using Upsert in mongodb

I'm using the angular-fullstack generator so there's 7 files in one endpoint (index, index.spec, orders.controller, orders.events, orders.integration, orders.model, and orders.socket). I'm not sure where to do computation to store in the fields when there is a PUT/Upsert. All the examples that I can google either use virtual fields or have generic code to do the computation. I know the computation I need to do but have no idea where to put it using this generator.
After a bit more searching this morning, I think what I want is to use getters/setters?
It's working in the controller as I presumed but i'm not sure if it's the best place to put these simple
function doCalcsSingle(res) {
var tOrderitems = 0;
var tRecitems = 0;
var tMissingitems = 0;
var today = new Date();
for(var i = 0; i < res.body.items.length; i++) {
res.body.items[i].missingItems = res.body.items[i].numOfOrdItems - res.body.items[i].numOfRecItems;
if(res.body.items[i].missingItems < 0 || !res.body.items[i].missingItems) {
res.body.items[i].missingItems = 0;
}
res.body.items[i].totalPrice = res.body.items[i].numOfOrdItems * res.body.items[i].unitPrice;
tOrderitems = tOrderitems + res.body.items[i].numOfOrdItems;
tRecitems = tRecitems + res.body.items[i].numOfRecItems;
tMissingitems = tMissingitems + res.body.items[i].missingItems;
if(tMissingitems < 0 || !tMissingitems) {
tMissingitems = 0;
}
}
res.body.totalOrdItems = tOrderitems;
res.body.totalRecItem = tRecitems;
res.body.totalItemsMissing = tMissingitems;
res.body.lastUpdated = today;
if(tMissingitems <= 0) {
res.body.activeOrder = false;
res.body.completedDate = today;
} else {
res.body.activeOrder = true;
}
return res;
}

Can not save array in shared object as3

I have this code in my simple flash. I want to save name and score in my quiz. My code reference in this website http://www.mollyjameson.com/blog/local-flash-game-leaderboard-tutorial/
I want to make my code in just one actionscript. But I didn't success do it.
var m_FlashCookie = SharedObject.getLocal("LeaderboardExample");
var EntryName:String ="nama kamu";
var EntryScore:String ="nilai";
const NUM_SCORES_SAVED:int = 10;
inputBoxScore.text = EntryScore;
inputBoxName.text = EntryName
var latest_score_object:Object = {
name: EntryName,
score: EntryScore
};
var arr:Array;
arr = m_FlashCookie.data.storedArray
if ( arr == null)
{
arr = new Array();
}
arr.push( latest_score_object );
arr.sortOn("score", Array.NUMERIC | Array.DESCENDING);
if ( arr.length < NUM_SCORES_SAVED )
{
arr.pop();
}
btnSave.addEventListener(MouseEvent.CLICK, saveData);
function saveData(event:Event):void
{
m_FlashCookie.data.arr = arr;
m_FlashCookie.flush();
}
var myHTMLL:String = "";
var total_stored_scores:int = arr.length;
btnLoad.addEventListener(MouseEvent.CLICK, loadData);
function loadData(event:Event):void
{
for (var i:int = 0; i < total_stored_scores; ++i)
{
// loop through every entry, every entry has a "name" and "score" field as that's what we save.
var leaderboard_entry:Object = arr[i];
// is this the last score that was just entered last gamestate?
if ( leaderboard_entry == latest_score_object )
{
myHTMLL += (i+1) + ". <b><font color=\"#0002E5\">"+ leaderboard_entry.name + " " + leaderboard_entry.score +"</font></b><br>";
}
else
{
myHTMLL += (i+1) + ". "+ leaderboard_entry.name + " " + leaderboard_entry.score +"<br>";
}
}
myHTML.text = myHTMLL;
}
Can anybody help me?
You're saving the array as data.arr but reading the array as data.storedArray. You need to make them the same.
In other words, you've written this:
m_FlashCookie.data.arr = arr;
And when you load:
arr = m_FlashCookie.data.storedArray;
This clearly doesn't make sense: data.storedArray is never set, so it will never have a value, so you will always end up with a new empty array.
You need to use the same property on the shared object data. For example:
m_FlashCookie.data.storedArray = arr;
m_FlashCookie.flush();
Looking at your code, there's a number of other issues:
The latest score is immediately removed because arr.length < NUM_SAVED_SCORES is going to be true from the start, since arr starts out empty, and it then calls arr.pop() which will remove the latest entry that was just added. So the array is always empty.
It adds the score immediately with arr.push(latest_score_object) instead of waiting until the user clicks save, so the value of the input texts don't matter at all -- the saved values will always be "nama kamu" and "nilai".
The following fixes all the issues mentioned:
var leaderboard = SharedObject.getLocal("leaderboard");
const MAX_SAVED_SCORES:int = 10;
inputBoxName.text = "nama kamu";
inputBoxScore.text = "nilai";
var entries:Array = leaderboard.data.entries || [];
var latestEntry:Object;
displayScores();
btnLoad.addEventListener(MouseEvent.CLICK, loadClick);
btnSave.addEventListener(MouseEvent.CLICK, saveClick);
function loadClick(e:MouseEvent):void {
displayScores();
}
function saveClick(e:MouseEvent):void {
saveLatestScore();
displayScores();
}
function saveLatestScore():void {
// create the latest entry based on input texts
latestEntry = {
name: inputBoxName.text,
score: inputBoxScore.text
};
// add the entry and sort by score, highest to lowest
entries.push(latestEntry);
entries.sortOn("score", Array.NUMERIC | Array.DESCENDING);
// if reached the limit, remove lowest score
if (entries.length > MAX_SAVED_SCORES) {
entries.pop();
}
// store new sorted entries to shared object
leaderboard.data.entries = entries;
leaderboard.flush();
}
function displayScores():void {
var myHTMLL:String = "";
for (var i:int = 0; i < entries.length; ++i) {
// loop through every entry, every entry has a "name" and "score" field as that's what we save.
var entry:Object = entries[i];
// is this the last score that was just entered last gamestate?
if (entry == latestEntry)
myHTMLL += (i+1) + ". <b><font color=\"#0002E5\">"+ entry.name + " " + entry.score +"</font></b><br/>";
else
myHTMLL += (i+1) + ". "+ entry.name + " " + entry.score +"<br/>";
}
myHTML.htmlText = myHTMLL;
}

How to implement a do while loop on a promise on angularjs

I'm quite stuck in the development of an app right now. What i want to do is upon submission by ng-click the following task will be performed:
generate a 5 digit random number.
this random number will then be validated in the database if exist.
if it exist it will generate another number which will then be validated again until such time that the value returns to zero.
for number 1 i already have this:
var gRandomNum = function(){
var snumRand = Math.floor((Math.random()*10000)+1);
var numRand = snumRand.toString();
var str_f = numRand.length;
if(str_f == 1){
str_final = "0000" + numRand;
} else if(str_f == 2){
str_final = "000" + numRand;
} else if(str_f == 3){
str_final = "00" + numRand;
} else if(str_f == 4){
str_final = "0" + numRand;
} else {
str_final = numRand;
}
return str_final;
}
for number 2
var validataRandNum = function(pdata){
return $http.get('api/cntTc/'+pdata).
success(function(data){
return data.tc_count;
});
}
for number 3
do{
var pdata = gRandomNum();
var ifValid = validataRandNum(pdata);
} while(ifValid < 0);
Here is what it looks like on my Scope function
$scope.ok = function(){
do{
var pdata = gRandomNum();
var ifValid = validataRandNum(pdata);
} while(ifValid < 0);
}
When i tried to verify the value of ifValid all i'm getting is undefined but when i clicked again the value will show up but it was from the last clicked value. I tried to implement a promise but got stucked on how to implement it inside a promise. If you can provide a code that will do just that it will be great.
Is there any way to move this to the server side?
To stick to doing this on the client, perhaps you can try to have validateRandNum() call itself recursively (but consider putting in some limits so it doesn't go on forever)...
var validataRandNum = function(getRandNumFunc, deferred){
deferred = deferred || $q.defer();
var pdata = getRandNumFunc();
$http.get('api/cntTc/'+pdata).
success(function(data){
if (data.tc_count < 0) {
validataRandNum(getRandNumFunc, deferred);
} else {
deferred.resolve(data.tc_count);
}
});
return deferred.promise;
};
$scope.ok = function(){
validataRandNum(gRandomNum).then(function (tc_count) {
$scope.tc_count = tc_count;
});
};

JavaScript timer is resetting while refreshing the page

I got a count down timer script.. I'm going to use it for a online examination.. But now the problem is it is resetting while refreshing the page...
Any idea to prevent the resetting the time and continue without any problem if they refresh the page too?
here is the code
<script>
var mins;
var secs;
function cd() {
mins = 1 * m("2"); // change minutes here
secs = 0 + s(":01"); // change seconds here (always add an additional second to your total)
redo();
}
function m(obj) {
for(var i = 0; i < obj.length; i++) {
if(obj.substring(i, i + 1) == ":")
break;
}
return(obj.substring(0, i));
}
function s(obj) {
for(var i = 0; i < obj.length; i++) {
if(obj.substring(i, i + 1) == ":")
break;
}
return(obj.substring(i + 1, obj.length));
}
function dis(mins,secs) {
var disp;
if(mins <= 9) {
disp = " 0";
} else {
disp = " ";
}
disp += mins + ":";
if(secs <= 9) {
disp += "0" + secs;
} else {
disp += secs;
}
return(disp);
}
function redo() {
secs--;
if(secs == -1) {
secs = 59;
mins--;
}
document.getElementById("disp").innerHTML=dis(mins,secs); // setup additional displays here.
if((mins == 0) && (secs == 0)) {
window.alert("Time is up. Press OK to continue."); // change timeout message as required
// window.location = "yourpage.htm" // redirects to specified page once timer ends and ok button is pressed
} else {
cd = setTimeout("redo()",1000);
}
}
function init() {
cd();
}
window.onload = init;
</script>
If the page is refreshed, all you javascript code is re-executed. This is normal behaviour.
If you absolutely need to continue where you left, you can use the local storage API (only available in modern browsers) to store the time (every second you update the value).
When the page is loaded, you can then check if the value exists in Local storage, and start from where you were.
Are you sure you need this behaviour BTW?

Resources